c# - WPF-对话框相对源绑定(bind)(MVVM)

标签 c# wpf mvvm data-binding

我有一个 WPF 对话框,我正在尝试访问所有者的 ViewModel 中的一个属性。

我尝试了以下方法,但它绑定(bind)到对话框的 ViewModel:

<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, 
        AncestorType={x:Type Window}}, Path=DataContext.Property}"/>

我也试过:
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, 
        AncestorType={x:Type Window}}, Path=Owner.DataContext.Property}"/>

但它给出了相同的结果。

生成对话框的代码用户是:
        var dialog = new Dialog(DialogViewModel)
        {
            Owner = Window.GetWindow(this)
        };

我在 StackOverflow 中看到了几个问题,但似乎都没有。

有任何想法吗?
是否可以在对话中有相对来源?

最佳答案

如果我在子窗口上明确设置 Owner,这对我有用:

<ComboBox 
    ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=Owner.DataContext.Property}"/>

然而 :有一个重要的警告,我认为这可能是您遇到的问题:如果子窗口是父窗口的私有(private)成员并且我在显示子窗口之前设置了所有者,它会尝试在子窗口显示之前解决绑定(bind). Owner当时为null,以后再设置Owner时不再尝试。

但是,如果我在显示它的方法中创建一个新的子窗口实例,设置 Owner,然后在其上调用 ShowDialog(),则绑定(bind)将使用 Owner 的非空值正确解析。我有理由相信,这样做的原因是 Owner 不是 DependencyProperty,也不会引发 PropertyChanged,因此不会发生任何更新以响应 Owner 的值更改。如果我在 UI 线程阻塞事件处理程序时将它设置在窗口的新实例上,那么新窗口实例直到设置其所有者之后才开始对绑定(bind)执行任何操作。但如果我早点创建它,然后让 UI 线程运行,那已经太晚了。

这不是你想要搞砸的事情。

我的建议:

给你的子窗口一个像这样的属性:
#region OwnerDataContext Property
public Object OwnerDataContext
{
    get { return (Object)GetValue(OwnerDataContextProperty); }
    set { SetValue(OwnerDataContextProperty, value); }
}

public static readonly DependencyProperty OwnerDataContextProperty =
    DependencyProperty.Register("OwnerDataContext", typeof(Object), typeof(SubWindow),
        new PropertyMetadata(null));
#endregion OwnerDataContext Property

然后当你显示子窗口...
var dialog = new Dialog(DialogViewModel)
{
    Owner = Window.GetWindow(this),
    OwnerDataContext = DataContext
};

作为一个 DependencyProperty,绑定(bind)将与它正确交互。所有者窗口可以随意设置,可以绑定(bind)。绑定(bind)的工作方式,它是鸭子类型的,所以对于 OwnerDataContext 的绑定(bind)完全没有关系。有一个声明的对象类型。反正都是反射(reflection)。
<ComboBox 
    ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=OwnerDataContext.Property}"/>

对于您的代码为什么不起作用,我可能完全错了,但我敢打赌这无论如何都会起作用。

关于c# - WPF-对话框相对源绑定(bind)(MVVM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38020484/

相关文章:

c# - 异常 : Maximum number of items that can be serialized or deserialized in an object graph is '65536'

c# - 如何在 Angular 和 Asp.Net Boilerplate 上获取当前用户 ID?

C# 检查文本文件是否有内容

wpf - 在 DataTemplate 中绑定(bind) Grid.Row/Grid.Column

java - 观察通过改造更改的实时数据不会在更改时触发

WPf、MEF 架构设计

c# - 如何使用 asp.net MVC 在可折叠列表中表示模型数据

c# - 如何在 MVC3 View 中从 Markdown 文本中突出显示 C# 语法

c# - WPF - 使用 DisplayMemberBinding 向 GridViewColumn 添加工具提示

c# - 使用 pack uri 在 winforms 中加载图像