簡體   English   中英

Xamarin iOS自定義ListView

[英]Xamarin iOS Custom ListView

我在StackedLayout中使用ListView的大小遇到麻煩。 我希望ListView僅占用所包含項目所需的空間。 但是,我的ListView幾乎總是占據那里的所有空間,即使它僅包含大約3個項目。

有沒有一種方法可以創建自定義DynamicListView並覆蓋某些在添加或刪除項時計算自定義大小的方法? 例如,我希望列表在任何空白時都消失。 誰能告訴我,哪些方法可以替代和/或對添加/刪除到基礎模型的項目如何反應?

我的直覺告訴我這樣的事情:

namespace Foo.Controls
{
    public class SpottedView : ListView
    {
        public SpottedView()
        {
        }

        protected override void OnChildAdded(Element child)
        {
            Console.WriteLine($"{Util.methodName()}");
            base.OnChildAdded(child);
            InvalidateMeasure();
        }

        protected override void OnChildRemoved(Element child)
        {
            Console.WriteLine($"{Util.methodName()}");
            base.OnChildRemoved(child);
            InvalidateMeasure();
        }
    }
}

我找到了解決方案。 我從StackLayout更改為Grid ,如下所示:

<ContentPage.Content>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <ctrl:CameraView Grid.Row="0" />
        <ctrl:SpottedView Grid.Row="1" RowHeight="40" />

    </Grid>
</ContentPage.Content>

然后我添加了一個自定義ListViewSpottedView ,如下所示:

namespace Foo.Controls
{
    public class SpottedView : ListView
    {
        ObservableCollection<string> items;

        public SpottedView() : base()
        {
            items = new ObservableCollection<string>();
            ItemsSource = items;
            items.CollectionChanged += onItemsChanged;

            // TODO: test purposes, remove later
            var autoEvent = new AutoResetEvent(false);
            var stateTimer = new Timer(onTimer, autoEvent, 1000, 2000);
        }

        void onItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            MainThread.BeginInvokeOnMainThread(() =>
            {
                HeightRequest = RowHeight * items.Count;
                InvalidateMeasure();
            });
        }

        // TODO test purposes, remove later.
        void onTimer(object state)
        {
            MainThread.BeginInvokeOnMainThread(() =>
            {
                if (items.Count < 2)
                {
                    items.Add("Blah");
                }
                else
                {
                    items.Clear();
                }
            });
        }
    }
}

奇跡般有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM