微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Xamarin Forms 中为 Treeview 创建可绑定属性

如何解决在 Xamarin Forms 中为 Treeview 创建可绑定属性

我需要在我的 xamarin 表单应用程序中使用 Treeview,但是网络上唯一现有的 TreeView 不是免费的(Syncfusion 和 Telerik)。

所以我发现了这个非常有趣的项目:https://github.com/AdaptSolutions/Xamarin.Forms-TreeView

我发现的唯一问题是 ItemSource 和 SelectedItem 属性不可绑定,因此我无法在 MVVM 模式上使用它。这就引出了我的问题,我怎样才能使它们可绑定。

我尝试遵循此文档:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/bindable-properties

但还是没有。任何人都可以帮我吗?谢谢

更新:

这是 TreeView 类:

public class TreeView : ScrollView
    {
        #region Fields
        private readonly StackLayout _StackLayout = new StackLayout { Orientation = StackOrientation.Vertical };

        //Todo: This initialises the list,but there is nothing listening to INotifyCollectionChanged so no nodes will get rendered
        private IList<TreeViewNode> _RootNodes = new ObservableCollection<TreeViewNode>();
        private TreeViewNode _SelectedItem;
        #endregion

        #region Public Properties

        public TreeViewNode SelectedItem
        {
            get => _SelectedItem;

            set
            {
                if (_SelectedItem == value)
                {
                    return;
                }

                if (_SelectedItem != null)
                {
                    _SelectedItem.IsSelected = false;
                }

                _SelectedItem = value;

                selecteditemchanged?.Invoke(this,new EventArgs());
            }
        }

      
        public IList<TreeViewNode> RootNodes
        {
            get => _RootNodes;
            set
            {
                _RootNodes = value;

                if (value is INotifyCollectionChanged notifyCollectionChanged)
                {
                    notifyCollectionChanged.CollectionChanged += (s,e) =>
                    {
                        RenderNodes(_RootNodes,_StackLayout,e,null);
                    };
                }

                RenderNodes(_RootNodes,new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset),null);
            }
        }

        #endregion


        #region Constructor
        public TreeView()
        {
            Content = _StackLayout;
        }
        #endregion

        

        #region Private Static Methods
        private static void AddItems(IEnumerable<TreeViewNode> childTreeViewItems,StackLayout parent,TreeViewNode parentTreeViewItem)
        {
            foreach (var childTreeNode in childTreeViewItems)
            {
                if (!parent.Children.Contains(childTreeNode))
                {
                    parent.Children.Add(childTreeNode);
                }

                childTreeNode.ParentTreeViewItem = parentTreeViewItem;
            }
        }
        #endregion

        

        #region Internal Static Methods
        internal static void RenderNodes(IEnumerable<TreeViewNode> childTreeViewItems,NotifyCollectionChangedEventArgs e,TreeViewNode parentTreeViewItem)
        {
            if (e.Action != NotifyCollectionChangedAction.Add)
            {

                AddItems(childTreeViewItems,parent,parentTreeViewItem);
            }
            else
            {
                AddItems(e.NewItems.Cast<TreeViewNode>(),parentTreeViewItem);
            }
        }
        #endregion
    }

所以我在这里尝试做的是使 RootNodes 以及之后的 SelectedItem 可绑定。

我所做的只是添加了这个,认为它应该可以工作,但显然它没有:

public static readonly BindableProperty RootNodesProperty =
            BindableProperty.Create(nameof(RootNodes),typeof(IList<TreeViewNode>),typeof(TreeView));

        public IList<TreeViewNode> RootNodes
        {
            get => (IList<TreeViewNode>)GetValue(RootNodesProperty);
            set
            {
                SetValue(RootNodesProperty,value);
                _RootNodes = value;
                if (value is INotifyCollectionChanged notifyCollectionChanged)
                {
                    notifyCollectionChanged.CollectionChanged += (s,null);
            }
        }

更新2: 这是它的样子

enter image description here

希望能帮到你

解决方法

您似乎不需要在 ScrollView 中创建自定义 ItemSourceSelectedItem,因为 Xamarin Foms 具有包含 ItemsSourceItemTemplateSelector .

可绑定布局允许从 Layout 类派生的任何布局类通过绑定到项目集合来生成其内容,并可以选择使用 DataTemplate 设置每个项目的外观。可绑定布局由 BindableLayout 类提供,该类公开以下附加属性:

  • ItemsSource – 指定要由布局显示的 IEnumerable 项的集合。
  • ItemTemplate – 指定要应用于布局显示的项目集合中的每个项目的 DataTemplate。
  • ItemTemplateSelector – 指定将用于在运行时为项目选择 DataTemplate 的 DataTemplateSelector。

如果需要使用ScrollView,示例代码如下:

<ScrollView>
 <StackLayout BindableLayout.ItemsSource="{Binding User.TopFollowers}"
             Orientation="Horizontal"
             ...>
    <BindableLayout.ItemTemplate>
        <DataTemplate>
            <controls:CircleImage Source="{Binding}"
                                  Aspect="AspectFill"
                                  WidthRequest="44"
                                  HeightRequest="44"
                                  ... />
        </DataTemplate>
    </BindableLayout.ItemTemplate>
 </StackLayout>
</ScrollView>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?