首页 > 解决方案 > WPF绑定到另一个窗口的属性

问题描述

我有以下配置:

主窗口.xaml

<Window x:Class="MYNS.MainWindow"
        mc:Ignorable="d"
        x:Name="mainWindow"
        ...

主窗口.xaml.cs

public partial class MainWindow : Window
{
    public Options Options { get; private set; }

    public MainWindow()
    {
        Options = new Options();
    }
}

选项.xaml

class Options 
{
    public bool QuietMode { get; set; }

    public Options()
    {
        QuietMode = true;
    }
}

现在我想将此布尔值绑定到CheckBox另一个窗口的控件,所以我有

选项Windows.xaml

<CheckBox 
  Content="Quiet Mode" 
  DataContext="{Binding ElementName=mainWindow, Path=Options}"
  IsChecked="{Binding Path=QuietMode}"
/>

我虽然打算这样做,但它不起作用(我尝试了多种类似的方法,但到目前为止都没有奏效)。由于我对 WPF 很陌生,我想我显然在这里遗漏了一些东西。

标签: c#wpfxamldata-binding

解决方案


绑定ElementName只能在同一个 UserControl 内工作。如果两个 Windows 完全分开,除了将 Options 属性从 MainWindow 类移动到适当的 Model 或 ViewModel 类之外,您别无选择,无论如何您都应该这样做,因为这就是 WPF/MVVM 应该是的方式。

如果你真的想从一个视图绑定到另一个视图,不同的 Window 实例至少应该共享一些共同的祖先,这样你就可以使用 Binding 参数而不是Binding 参数ElementNameFindAncestor但我怀疑这将是一个简单或自然的,甚至可能的解决方案。(我认为这甚至是不可能的,因为 Window 是一个“顶级控件”,它在Logical 或 Visual Trees中没有父级。

到目前为止,最好的解决方案是尽快将模型数据从视图中取出,您将获得一个更容易改进的环境。


更新:一些 MVVM 上下文:

通常在 WPF 应用程序中,您有一些与“视图”层(Windows、控件、复选框)相关的类和其他与“[View]Model”层相关的类,您将在其中放置选项类。您需要以一种方式引导您的应用程序,在启动执行过程中,您很快就会有一个 View 实例和一个 ViewModel 实例,后者应该设置为前者的 DataContext,这样您就可以使用数据绑定。

围绕“View-First”与“Model-First”方法存在一些宗教战争,但我不使用任何一种:我总是有一个BootStrapper创建 MainView(通常是 Window)和 MainViewModel 的类,并让每个类树句柄本身。

一个例子:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        var window = new MainWindow();
        var vm = new MainViewModel();
        window.DataContext = vm;
        window.Show();
    }
}

但请记住,没有“一种正确的方法”可以做到这一点。不幸的是,你必须决定什么最适合你。


推荐阅读