标签的WPF DataBinding

时间:2014-04-15 09:51:21

标签: c# wpf

我现在正在尝试数小时来进行数据绑定运行。 但无论我什么都不尝试。 在几个thousend例子和重试(感觉就像一个ffew千)后,我决定为我的问题创建一个新线程。

我有一个窗口,您可以选择一个工人。 在这些窗口中有一个UserControl,显示所选工作人员的详细信息。 如果所选工人发生了变化,那么自动填充所有标签/文本框/组合框将会很不错。

为此,UserControl有一个Property" 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;
    }

UserControl上的标签:

<Label Height="28" Margin="129,6,6,0" Name="labelWorkerID" VerticalAlignment="Top" Content="{Binding ID, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"></Label>

我将ShownWorker设置为:

private void dataGridAvaibleWorker_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (dataGridAvaibleWorker.SelectedItem is Worker)
        {
            var selectedWorker= (Worker)dataGridAvaibleWorker.SelectedItem;
            WorkerDetails.ShownWorker = selectedWorker;
        }
    }

但没有任何反应。怎么了? 我不明白。

1 个答案:

答案 0 :(得分:0)

除了财产更改通知外,您还有另一个问题:

这两个属性:

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

提出属性更改事件

更好的方法是使用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
    }
}

现在您有了一个VM,您可以将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东西 - 我建议看看一些流行的MVVM框架,因为他们可以轻松地使用WPF / Silverlight。

我个人最喜欢的是Caliburn Micro,但有很多(MVVMLight,Prism等)