Xamarin表单自定义可绑定属性未更新
我试图弄清楚如何更新自定义控件中的自定义属性。我的问题是,当我在viewmodel中修改集合时,它不会触发控件内部的更新。然而,在调试pupos时,我将一个lsitview放入我想要可视化的项目中,我可以看到它们正确地显示出来Xamarin表单自定义可绑定属性未更新,xamarin,xamarin.forms,data-binding,Xamarin,Xamarin.forms,Data Binding,我试图弄清楚如何更新自定义控件中的自定义属性。我的问题是,当我在viewmodel中修改集合时,它不会触发控件内部的更新。然而,在调试pupos时,我将一个lsitview放入我想要可视化的项目中,我可以看到它们正确地显示出来 <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms&
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="clr-namespace:Xamarin.CommunityToolkit.UI.Views;assembly=Xamarin.CommunityToolkit"
xmlns:viewmodels="clr-namespace:Treeview_DragAndDrop.ViewModels"
x:Class="Treeview_DragAndDrop.MainPage"
xmlns:controls="clr-namespace:Treeview_DragAndDrop.Controls">
<ContentPage.BindingContext>
<viewmodels:HomeScreenViewModel />
</ContentPage.BindingContext>
<StackLayout>
<StackLayout Orientation="Horizontal">
<controls:TreeviewControl ItemsSource="{Binding Path=FromTreeList,Mode=TwoWay}" WidthRequest="500"></controls:TreeviewControl>
<controls:TreeviewControl ItemsSource="{Binding Path=ToTreeList,Mode=TwoWay}" WidthRequest="500"></controls:TreeviewControl>
</StackLayout>
<ListView ItemsSource="{Binding Path=FromTreeList}"></ListView>
</StackLayout>
视图模型
public class HomeScreenViewModel
{
private ObservableCollection<TreeNodeModel> toTreeList;
private ObservableCollection<TreeNodeModel> fromTreeList;
public ObservableCollection<TreeNodeModel> FromTreeList { get => fromTreeList; set => fromTreeList = value; }
public ObservableCollection<TreeNodeModel> ToTreeList { get => toTreeList; set => toTreeList = value; }
public HomeScreenViewModel()
{
FromTreeList = new ObservableCollection<TreeNodeModel>();
ToTreeList = new ObservableCollection<TreeNodeModel>();
Task.Run(() => CreateTreeListCollections());
}
private void CreateTreeListCollections()
{
Thread.Sleep(10000);
Device.BeginInvokeOnMainThread(() =>
{
FromTreeList.Add(new TreeNodeModel()
{
Id = 1,
Text = "Első",
Children = new List<TreeNodeModel>()
{
new TreeNodeModel() {
Id = 2,
Text = "Első.Egy",
}
}
});
FromTreeList.Add(new TreeNodeModel()
{
Id = 1,
Text = "Masodik",
Children = new List<TreeNodeModel>()
{
new TreeNodeModel() {
Id = 2,
Text = "Masodik.Egy",
Children=new List<TreeNodeModel>()
{
new TreeNodeModel(){
Id = 1,
Text = "Masodik.Egy.Egy",
Children = new List<TreeNodeModel>()
{
new TreeNodeModel() {
Id = 2,
Text = "Masodik.Egy.Egy.Egy",
}
}
}
}
}
}
});
});
Device.BeginInvokeOnMainThread(() =>
{
ToTreeList.Add(new TreeNodeModel()
{
Id = 1,
Text = "Első",
Children = new List<TreeNodeModel>()
{
new TreeNodeModel() {
Id = 2,
Text = "Első.Egy",
}
}
});
ToTreeList.Add(new TreeNodeModel()
{
Id = 1,
Text = "Első",
Children = new List<TreeNodeModel>()
{
new TreeNodeModel() {
Id = 2,
Text = "Első.Egy",
}
}
});
});
}
}
公共类HomeScreenView模型
{
私人可观察到的收集到文件列表;
来自树列表的私有可观察收集;
公共ObservableCollection FromTreeList{get=>FromTreeList;set=>FromTreeList=value;}
公共ObservableCollection ToTreeList{get=>ToTreeList;set=>ToTreeList=value;}
公共HomeScreenView模型()
{
FromTreeList=新的ObservableCollection();
ToTreeList=新的ObservableCollection();
运行(()=>CreateTreeListCollections());
}
私有void CreateTreeListCollections()
{
睡眠(10000);
Device.beginInvokeMainThread(()=>
{
添加(新的treenodemel()
{
Id=1,
Text=“Első”,
Children=新列表()
{
新的Treenodemel(){
Id=2,
Text=“Első.Egy”,
}
}
});
添加(新的treenodemel()
{
Id=1,
Text=“Masodik”,
Children=新列表()
{
新的Treenodemel(){
Id=2,
Text=“Masodik.Egy”,
Children=新列表()
{
新的Treenodemel(){
Id=1,
Text=“Masodik.Egy.Egy”,
Children=新列表()
{
新的Treenodemel(){
Id=2,
Text=“Masodik.Egy.Egy.Egy”,
}
}
}
}
}
}
});
});
Device.beginInvokeMainThread(()=>
{
添加(新的treenodemel()
{
Id=1,
Text=“Első”,
Children=新列表()
{
新的Treenodemel(){
Id=2,
Text=“Első.Egy”,
}
}
});
添加(新的treenodemel()
{
Id=1,
Text=“Első”,
Children=新列表()
{
新的Treenodemel(){
Id=2,
Text=“Első.Egy”,
}
}
});
});
}
}
我的自定义控件
public class TreeviewControl : ScrollView
{
private readonly StackLayout _StackLayout = new StackLayout { Orientation = StackOrientation.Vertical };
public ObservableCollection<TreeNodeModel> ItemsSource
{
get { return (ObservableCollection<TreeNodeModel>)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(propertyName: nameof(ItemsSource), returnType: typeof(ObservableCollection<TreeNodeModel>),
declaringType: typeof(TreeviewControl), defaultValue: new ObservableCollection<TreeNodeModel>(),
defaultBindingMode: BindingMode.TwoWay, propertyChanged: ItemsSourceChanged);
private static void ItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
{
var control = (TreeviewControl)bindable;
control.ItemsSource = (ObservableCollection<TreeNodeModel>)newValue;
if (control.ItemsSource != null)
{
Debug.WriteLine(control.ItemsSource.Count);
foreach (var rootNode in control.ItemsSource)
{
control._StackLayout.Children.Add(new TreeViewNode(rootNode).CreateNodeView());
}
}
}
public TreeviewControl()
{
Content = _StackLayout;
}
}
公共类树视图控件:滚动视图
{
私有只读StackLayout _StackLayout=newstacklayout{Orientation=StackOrientation.Vertical};
公共可观察收集项目来源
{
get{return(ObservableCollection)GetValue(ItemsSourceProperty);}
set{SetValue(ItemsSourceProperty,value);}
}
公共静态只读BindableProperty ItemsSourceProperty=BindableProperty.Create(propertyName:nameof(ItemsSource),returnType:typeof(ObservableCollection),
declaringType:typeof(TreeviewControl),defaultValue:new ObservableCollection(),
defaultBindingMode:BindingMode.TwoWay,propertyChanged:ItemsSourceChanged);
私有静态无效项SourceChanged(BindableObject bindable、object oldValue、object newValue)
{
var-control=(TreeviewControl)可绑定;
control.ItemsSource=(ObservableCollection)newValue;
if(control.ItemsSource!=null)
{
Debug.WriteLine(control.ItemsSource.Count);
foreach(control.ItemsSource中的var rootNode)
{
控件。_StackLayout.Children.Add(新的TreeViewNode(rootNode.CreateNodeView());
}
}
}
公共树控件()
{
内容=_堆栈布局;
}
}
您可以查看以使用CollectionChanged事件。