繁体   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