xamarin - 在 Xamarin 表单中为 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, _StackLayout, 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, StackLayout parent, NotifyCollectionChangedEventArgs e, TreeViewNode parentTreeViewItem)
{
if (e.Action != NotifyCollectionChangedAction.Add)
{
AddItems(childTreeViewItems, parent, parentTreeViewItem);
}
else
{
AddItems(e.NewItems.Cast<TreeViewNode>(), parent, 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, e) =>
{
RenderNodes(_RootNodes, _StackLayout, e, null);
};
}
RenderNodes(_RootNodes, _StackLayout, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset), null);
}
}
希望这可以帮助
解决方案
看来您不需要在ScrollViewItemSource
中创建自定义and ,因为 Xamarin Foms 具有包含and的可绑定布局。SelectedItem
ItemsSource
ItemTemplateSelector
可绑定布局使派生自 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>
推荐阅读
- amazon-web-services - 如何使用 Xshell 6 连接 aws ec2
- response - 在 Dialogflow Assistant 中自定义帐户链接消息
- angular - 无法构建离子项目
- oracle-data-integrator - oracle ODI删除IKM sql增量更新中的所有选项有事务吗?
- yugabyte-db - 如何在 yugabyte-db 中设置 Universe 名称和命名空间?
- typescript - Typescript中“数字”和“任何”之间的类型关系是什么?
- java - 有没有办法让python产生与java相同的结果按位左移?
- css - SCSS 中的 Flexbox 多类选择器
- c# - 处理保存文件迁移的最佳方法
- node.js - 开玩笑测试通过但得到错误:最后连接 ECONNREFUSED 127.0.0.1:80