C# 标签的WPF数据绑定

C# 标签的WPF数据绑定,c#,wpf,C#,Wpf,我现在花了好几个小时试图运行数据绑定。 但不管我做什么,都没用。 经过几千次的示例和重试(感觉像是几千次),我决定为我的问题创建一个新的线程 我有一个窗口,你可以选择一个炒锅。 在这些窗口上有一个UserControl,显示所选工作程序的详细信息。 如果选定的工作人员发生更改,那么自动填充所有标签/文本框/组合框将是一件好事 为此,UserControl有一个属性“ShownWorker”,其中包含所选的工作进程 工人阶级: public class Worker : INotifyPr

我现在花了好几个小时试图运行数据绑定。 但不管我做什么,都没用。 经过几千次的示例和重试(感觉像是几千次),我决定为我的问题创建一个新的线程

我有一个窗口,你可以选择一个炒锅。 在这些窗口上有一个UserControl,显示所选工作程序的详细信息。 如果选定的工作人员发生更改,那么自动填充所有标签/文本框/组合框将是一件好事

为此,UserControl有一个属性“ShownWorker”,其中包含所选的工作进程

工人阶级:

    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,它可以工作,但看起来没问题。有没有一种优雅的方法可以做到这一点?