用另一个对象替换当前绑定源对象

时间:2013-02-12 16:11:09

标签: c# wpf data-binding

我是C#和WPF的新手,我正在努力使用数据绑定。我有一个实现INotifyPropertyChanged的MyClass;因此,每当我更改属性值时,都会在我的UI中更新。然后我将stackpanel的DataContext绑定到MyClass的对象。像这样:

<StackPanel Name="stackPanel1" DataContext="{Binding}">
        <TextBlock Name="textBlock1" Text="{Binding Path=Title, Mode=OneWay}" />
</StackPanel>

在代码背后,我这样做:

item = new MyClass();
stackPanel1.DataContext = item;

并且绑定工作正常。如果我用另一个替换当前的绑定源对象,我必须通过再次输入datacontext绑定来手动设置它:

item = new MyClass();
stackPanel1.DataContext = item;
item1 = new MyClass();
.
. //manipulate item1
.
if (item1 is ok)
   item=item1;
   stackPanel1.DataContext = item;

有没有更好的方法来替换我的源对象并更新所有相关的绑定?

3 个答案:

答案 0 :(得分:1)

当您说stackPanel1.DataContext = item;时,您 设置 属性,而不是 绑定

设置属性时,您将其设置为等于对象的实例。当你绑定它时,你告诉它它将从其他位置获取它的值,所以当它需要获取值时,请查看该位置。

提供包含绑定属性的类实现INotifyPropertyChanged,然后只要绑定属性发生更改,UI就会收到警报,这会导致重新评估绑定。

例如,如果您最初使用

设置了DataContext
MyWindow.DataContext = this;

其中this是您的窗口,而您的窗口的类型为MyClass,称为Item,您可以使用以下<{p}}绑定DataContext

<StackPanel DataContext="{Binding Item}" ...>

并且只要您更新了属性Item,您的StackPanel DataContext也会更新(提供实施INotifyPropertyChanged)。

如果您有兴趣,我想在WPF中发布关于初学者概念的博客,您可能有兴趣查看我的文章What is this "DataContext" you speak of?,这是对DataContext是什么的一个非常简单的解释。以及它是如何使用的。

总而言之,WPF有两层:UI层和数据层。 DataContext是数据层,当您编写{Binding SomeProperty}时,实际上是绑定到数据层。通常,在后面的代码中设置数据层(DataContext)一次,然后在XAML中使用Bindings使UI层显示来自数据层的信息。

(您可能还有兴趣查看我的Simple MVVM Example,其中包含一个非常简单的工作代码示例,并说明了如何实现INotifyPropertyChanged以及UI层和数据层如何实现的一些示例完全分开)

答案 1 :(得分:0)

您可以在MainWindow(或UserControl或其他任何内容)中添加CurrentItem属性,并为该属性实施INotifyPropertyChange。然后设置

DataContext = this;
在MainWindow的构造函数中

并像这样绑定:

Text="{Binding Path=CurrentItem.Title}" 

现在每当你设置

var item = new MyClass();
...
CurrentItem = item;

绑定将会更新。

答案 2 :(得分:0)

DataContext="{Binding}"

stackPanel1.DataContext = item;

两者基本上都是一样的。不同之处在于,一个在XAML中完成,另一个在代码中完成。虽然第一个示例允许在给定绑定父级的情况下更新绑定,但每次要更改stackpanel附加的内容时,必须更新第二个绑定父级。恕我直言,你应该创建一个共同绑定的公共绑定父。这将允许您更改子绑定,而无需每次都设置上下文。

<StackPanel Name="parentPanel">
    <StackPanel Name="stackPanel1" DataContext="{Binding Path=Child}">
            <TextBlock Name="textBlock1" Text="{Binding Path=Title, Mode=OneWay}" />
    </StackPanel>
</StackPanel>


parent = new ParentClass();
parent.Child= new MyClass();
parentPanel.DataContext = parent ;

现在,如果在ParentClass上正确创建了notify属性,则可以更改子堆栈面板的绑定

parent.Child= new NewClass();