Xamarin.Forms-IndicatorView

IndicatorViewをCarouselViewと連携させないで単独で使う方法についての覚書。

CarouselViewのIndicatorViewでIndicatorViewのオブジェクトを指定して連携させるのが一般的なようなのだが、ちょっと今回連携させないで使ったらどうなのか、調べてみた。

まずは実際の描画内容


表示は、上の様にデフォルトだと〇の形状が表示される。
ただこの設定は以下の様な色の指定を入れた場合。色の指定をしない場合は何も表示されなかった。

IndicatorColor="LightGray"
SelectedIndicatorColor="DarkGray"

VMとの連携

IndicatorViewを単独で利用する場合は、CountとPositionを連携させればいい。
CarouselViewと連携させた場合、これら属性はCarouselViewと勝手にバインドされているらしい。

以下がView側とViewModel側のサンプルコード。

    <StackLayout>
        <Label Text="{Binding Position}"
            VerticalOptions="CenterAndExpand" 
            HorizontalOptions="CenterAndExpand" />
        <IndicatorView
        Count="{Binding Count}"
        Position="{Binding Position}"
        Margin="0,40"
        IndicatorColor="LightGray"
        SelectedIndicatorColor="DarkGray"
        HorizontalOptions="Center">
        </IndicatorView>
        <StackLayout.GestureRecognizers>
            <SwipeGestureRecognizer Direction="Left" Command="{Binding DownPage}"/>
            <SwipeGestureRecognizer Direction="Right" Command="{Binding UpPage}"/>
        </StackLayout.GestureRecognizers>
    </StackLayout>
    public class IndicatorTestViewModel : BaseViewModel
    {
        int position_;
        int count_;
        List<int> dummy_ = new List<int>();

        public int Position
        {
            get { return position_; }
            set { SetProperty(ref position_, value); }
        }

        public int Count
        {
            get { return count_; }
        }

        public List<int> Dummy
        {
            get { return dummy_; }
        }

        public Command UpPage { get; private set; }
        public Command DownPage { get; private set; }


        public IndicatorTestViewModel()
        {
            position_ = 0;
            count_ = 10;

            UpPage = new Command(() =>
            {
                if (Position < count_ -  1) {
                    Position++;
                }
            });

            DownPage = new Command(() =>
            {
                if (Position > 0) {
                    Position--;
                }
            });

            for (int i = 0; i < count_; i++) {
                dummy_.Add(i);
            }
        }
    }

問題

で、ここで問題が発生。

Android側は、想定通りインジケーターが表示されたのだけど、UWP側は表示されなかった。


想定では、上の赤丸部分にインジケーターが表示されるはずなのだけど、表示がされない。


こちらがAndroid版。きちんと表示されている。

一応ライブビジュアルツリーで見たら、IndicatorViewはあり画面上にもその領域があることは確認できた。

そこで、なんとなくだけどIndicatorTemplateを使い〇を表示してみたところ、そちらは表示された。

なのでIndicatorViewの動作自体は問題ないとは思った。

原因

色々調べてみたのだけど、xamarinのバグレポートにも上がっていなかった。
なのでgithubに上がっているUWPのレンダー処理をちょっと見たところ、Shapeを使った描画では、ItemsSourceを使ってShapeデータを作るというコードになっていた。

Xamarin.Forms/Xamarin.Forms.Platform.UAP/IndicatorViewRenderer.cs at 5.0.0 · xamarin/Xamarin.Forms
Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI. - xamarin/Xamarin.Forms

上のソースのvoid CreateIndicators()の真ん中あたり。

Countがあるんでそれで個数分のShapeを作ればいいんじゃないかと思ったのだけど、なぜItemsSourceが必要なんだろうか。

描画実装処理からヒントを得、上のサンプルソースのIndicatorViewにItemsSource="{Binding Dummy}"を追加したところ、UWPでもインジケーターが表示された。

バグレポートは出したけど、何時修正されるだろうか。

コメント

タイトルとURLをコピーしました