C# 标签的WPF数据绑定
我现在花了好几个小时试图运行数据绑定。 但不管我做什么,都没用。 经过几千次的示例和重试(感觉像是几千次),我决定为我的问题创建一个新的线程 我有一个窗口,你可以选择一个炒锅。 在这些窗口上有一个UserControl,显示所选工作程序的详细信息。 如果选定的工作人员发生更改,那么自动填充所有标签/文本框/组合框将是一件好事 为此,UserControl有一个属性“ShownWorker”,其中包含所选的工作进程 工人阶级:C# 标签的WPF数据绑定,c#,wpf,C#,Wpf,我现在花了好几个小时试图运行数据绑定。 但不管我做什么,都没用。 经过几千次的示例和重试(感觉像是几千次),我决定为我的问题创建一个新的线程 我有一个窗口,你可以选择一个炒锅。 在这些窗口上有一个UserControl,显示所选工作程序的详细信息。 如果选定的工作人员发生更改,那么自动填充所有标签/文本框/组合框将是一件好事 为此,UserControl有一个属性“ShownWorker”,其中包含所选的工作进程 工人阶级: public class Worker : INotifyPr
public class Worker : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private string id;
public string ID
{
get
{
return id;
}
set
{
id = value;
OnPropertyChanged("ID");
}
}
public Worker()
{
}
}
用户控制:
private Worker shownWorker;
public Worker ShownWorker
{
get
{
return shownWorker;
}
set
{
shownWorker = value;
}
}
public WorkerDetails()
{
InitializeComponent();
this.DataContext = shownWorker;
}
<Label Height="28" Margin="129,6,6,0" Name="labelWorkerID" VerticalAlignment="Top" Content="{Binding ID, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"></Label>
UserControl上的标签:
private Worker shownWorker;
public Worker ShownWorker
{
get
{
return shownWorker;
}
set
{
shownWorker = value;
}
}
public WorkerDetails()
{
InitializeComponent();
this.DataContext = shownWorker;
}
<Label Height="28" Margin="129,6,6,0" Name="labelWorkerID" VerticalAlignment="Top" Content="{Binding ID, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"></Label>
但什么也没发生。怎么了?
我不明白。除了属性更改通知之外,您还有一个问题: 这两个属性:
ShownWorker
DataContext
在窗体打开时指向同一引用-例如
Worker someWorker = new Worker();
ShownWorker = someWorker;
DataContext = ShownWorker;
在此处更改ShownWorker
不会影响DataContext
ShownWorker = new Worker();
此时,DataContext
仍然引用原始工作者-当您执行此分配时,DataContext=ShownWorker
,DataContext
引用您在三行中的第一行中实例化的工作者,它不引用ShownWorker
所指向的实例
要更好地解释它,请执行以下操作:
// I'll stick some 'tags' on to shown how the instances will be referenced
Worker someWorker = new Worker(); // someWorker = "Instance1"
ShownWorker = someWorker; // ShownWorker points to "Instance1"
DataContext = ShownWorker; // DataContext points to "Instance1"
ShownWorker = new Worker(); // ShownWorker now points to "Instance2"
// DataContext still points to "Instance1"
您需要设置DataContext
而不是ShownWorker
,并为DataContext
ShownWorker = new Worker();
更好的方法是使用MVVM方法,例如
public class WorkerViewModel : INotifyPropertyChanged
{
// Put standard INPC implementation here
public event PropertyChanged.... etc
private Worker shownWorker;
public Worker ShownWorker
{
get
{
return shownWorker;
}
set
{
if(value == shownWorker) return; // Don't do anything if the value didn't change
shownWorker = value;
OnPropertyChanged("ShownWorker");
}
}
public WorkerViewModel()
{
ShownWorker = // Get/create the worker etc
}
}
现在您有了虚拟机,您可以将DataContext
设置为:
public WorkerViewModel WorkerViewModel { get; private set; }
public WorkerDetails()
{
InitializeComponent();
WorkerViewModel = new WorkerViewModel();
this.DataContext = WorkerViewModel;
}
可以改为对VM进行更新:
WorkerViewModel.ShownWorker = someWorker;
确保在XAML中设置绑定
<UserControl>
<SomeControl DataContext="{Binding ShownWorker}" />
</UserControl>
我建议大家看看一些流行的MVVM框架,因为它们可以轻松地使用WPF/Silverlight
我个人最喜欢的是Caliburn Micro,但还有很多(MVVMLight、Prism等)您正在设置
ShownWorker
属性,但您没有为该属性引发PropertyChanged
事件-UI不知道ShownWorker
值已更改。属性更改事件仅通知UI属性已更改,它们不知道子/父属性,您必须为希望UI作出反应的所有属性实现属性更改事件。另外一个问题是,您正在将ShownWorker
属性设置为另一个对象引用-更改前者时,对引用的引用不会受到影响:您不能期望DataContext
将指向另一个对象引用对象当您更改DataContext
和ShownWorker
都指向的引用时,这是因为引用的工作方式-即使我在UserControl中实现PropertyChange事件并在ShownWorker的setter中引发PropertyChange事件,我也会在回答中解释。您正确的。如果我在ShownWorker的setter中再次设置dataContext,它可以工作,但看起来没问题。有没有一种优雅的方法可以做到这一点?