如何为多个 windows 创建一个 DataContext 实例?

How can I create only one instance of a DataContext for multiple windows?

所以我有一个 WPF 程序,其中有一个 ViewModel 和几个 windows。我通常像这样为我的 ViewModel 添加 DataContext:

<Window.DataContext>
    <local:PrintView x:Name="printerView"/>
</Window.DataContext>

但是如果我那样做,我会遇到创建多个 ViewModel 实例的问题,每个实例一个 window。这意味着如果我在一个 window 中更改 属性,另一个 window 的相同 属性 不会更改。

现在我在 App.xaml 中这样定义它:

<Application.Resources>

    <ResourceDictionary>
        <local:PrintView x:Key="printView"/>
    </ResourceDictionary>
</Application.Resources>

每个 window 中的地址如下:

DataContext="{StaticResource printView}"

但现在的问题是我想在没有 App.Xaml 的情况下创建整个内容。有谁知道我如何在没有 App.xaml 的情况下创建相同的结果?以及没有图书馆。

我正在使用 .NET Framework 4.8

编辑

我现在已经实现了来自@mm8 的解决方案。但是,它似乎仍然不起作用。 Xaml 部分一切正常,我可以访问这些属性。但是,后面的代码存在问题,即当我 select 一个 window 中的值并将其保存在 属性:

SecondWindow

因此将 selected 值保存在 属性:

SelectedItem="{Binding selected_printer, Mode=TwoWay}"

但是我想在另一个window中访问这个改变的值,是否像这样:

 var vm = (ViewModel)this.DataContext;
 vm.selected_printer

或者像这样:

ApplicationService.Instance.PrintView.selected_printer

无论我如何尝试在另一个 window 中访问之前更改的 属性,属性 都不会在另一个 window 中更新为新的 window值。

所以这个值: SecondWindow 未转移到其他window且未更新

我选择的打印机定义:

 private string _selected_printer;
    public string selected_printer
    {
        get
        {
            return _selected_printer;
        }
        set
        {
            _selected_printer = value;
            NotifyPropertyChanged(nameof(selected_printer));
        }
    }

我的 ViewModel 定义:

  public class PrintView: INotifyPropertyChanged

我的 属性 更改的内容:

 public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

您无需使用 App.xaml 即可创建全局资源。您可以创建自己的 application-wide 服务 class 并在那里设置您的视图模型:

public sealed class ApplicationService
{
    private ApplicationService() { }

    public static ApplicationService Instance { get; } = new ApplicationService();

    public PrintView PrintView { get; } = new PrintView();
}

用法:

DataContext="{Binding PrintView, Source={x:Static local:ApplicationService.Instance}}"

这基本上就是 view-model 定位器的工作原理(假设 PrintView 实际上是一个视图模型,尽管它的名字...)