将Window的DataContext绑定到WPF中的窗口本身

4

我有一个简单的对话框窗口,它继承自Window类,我正在通过XAML设置它的DataContext,如下所示:

<Window x:Class="MyProject.MyDialog"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        ...>
    <StackPanel>
        <TextBox Text="{Binding SomeText}"/>
        ...
    </StackPanel>
</Window>

以下是我展示此对话框的方式:

var dialog = new MyWindow();
MyWindow.SomeText = "some text";

if (dialog.ShowDialog() == true)
    ...

某种原因导致当窗口被创建并且没有绑定错误时,该文本框的初始文本未设置为"some text"。

然而,如果我将数据上下文设置为StackPanel而不是Window:

<StackPanel DataContext="{Binding RelativeSource={RelativeSource AncestorType=Window}}">
    ...
</StackPanel>

一切都如预期运行。

这两个方法的区别是什么?为什么第一种方法不起作用?


区别仅在于时机。当执行窗口构造函数时,将评估RelativeSource Self绑定,而当设置SomeText属性时,DataContext已经设置(因此您必须触发PropertyChanged事件)。RelativeSource AncestorType=Window绑定稍后评估,此时SomeText已经被设置,因此当设置DataContext时,绑定源属性已具有所需的值。 - Clemens
1个回答

0

你需要在窗口中实现 INotifyPropertyChanged 才能使第一个案例工作。

窗口本身没有被通知其属性(自身)已更改,因此 dc 没有被设置。


谢谢,但那不是我想问的问题,可以看一下我对@Theodosius回答的评论(我没有点踩)。 - szx
哈哈,我在他之前10分钟就发了同样的答案,重复发已经有人回答过的问题有什么意义呢?@theodosious - Muds
@szx,我可以解释其中的区别,但是我猜Theo这次会先发表他的看法。 - Muds
XAML实际上在构造函数执行完成时解析,因为Dispatcher会等待用户代码(在窗口的构造函数中)执行完毕,然后才执行其挂起的操作。这导致这些不同时刻的实际属性值不同,由于没有INotifyPropertyChanged,WPF无法更新UI以反映新的值。 - Muds

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接