刚用Databinding的同学会经常有各种各样失败的原因。最近在对Databinding对Collection做绑定的时候,犯了一个错误,感觉挺常见的,分享记录下:很多初学者大概以为ObservableCollection<> 任何改变的消息都会发一个事件告诉UI,但实际上是对ObservableCollection<>重新new一个地址,它并不会把新New 的地址发消息告诉UI,UI记录的source target的地址依然是之前的,除非你自己发消息告诉UI。
用一个简单的Databinding的例子说明,如下:
在UI 的ListBox绑定显示一个ObservableCollection<>,当点击了testButton后,在后台修改数据并显示。
点击testButton后
具体代码:
In XAML:
<UserControl x:Class="DataBindingReference.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<ListBox ItemsSource="{Binding Path=MClassBs}" DisplayMemberPath="MText"/>
<Button x:Name="textButton" Content="testButton" VerticalAlignment="Top" HorizontalAlignment="Left" Height="20" Width="80"Click="textButton_Click" Margin="0,61,0,0" />
</Grid>
</UserControl>
定义了一个ClassB
public class ClassB : ViewModelBase
{
public ClassB()
{
MText = "";
}
public ClassB(String showText)
{
MText = showText;
}
private String _mText;
public String MText
{
get
{
return _mText;
}
set
{
if (_mText != value)
{
_mText = value;
OnPropertyChanged("MText");
}
}
}
}
再定义一个ClassA
public classClassA :ViewModelBase
{
public ClassA()
{
MClassBs = new ObservableCollection<ClassB>();
MClassBs.Add(new ClassB("MyName"));
MClassBs.Add(new ClassB("HisName"));
}
public ObservableCollection<ClassB> MClassBs{get;set;}
}
对ClassA做DataBinding,注意注释部分Binding是错误的。因为你new 一个observableCollection <>后,mClass.MClassBs得到了新的地址,但是UI 一直记录的是原来的地址。所以新的地址并没有和UI产生DataBinding。
public partialclassMainPage :UserControl
{
ClassA mClass;
public MainPage()
{
InitializeComponent();
mClass=new ClassA();
LayoutRoot.DataContext = mClass;
}
private void textButton_Click(object sender,RoutedEventArgs e)
{
//mClass.MClassBs = new ObservableCollection<ClassB>();
//mClass.MClassBs.Add(new ClassB("Hello"));
mClass.MClassBs.Clear();
mClass.MClassBs.Add(new ClassB("Hello"));
}
}
如果要想注释的代码能work,必须给MClassBs赋值的时候,要发消息给UI知道。既然ObserverableCollection不发,我们自己发。修改ClassA如下:
namespace DataBindingReference
{
public class ClassA : ViewModelBase
{
public ClassA()
{
MClassBs = new ObservableCollection<ClassB>();
MClassBs.Add(new ClassB("MyName"));
MClassBs.Add(new ClassB("HisName"));
}
private ObservableCollection<ClassB> mClassBs;
public ObservableCollection<ClassB> MClassBs
{
get
{
return mClassBs;
}
set
{
if (mClassBs != value)
{
mClassBs = value;
OnPropertyChanged("MClassBs");
}
}
}
}
}
这样子再运行一次注释的代码就ok了。。