【问题标题】:How do I use the same ViewModel for two views?如何为两个视图使用相同的 ViewModel?
【发布时间】:2019-08-01 02:05:06
【问题描述】:

所以我的MainWindow.xamlBaseViewModel 的DataContext 设置如下。

<Window.DataContext>
    <viewModel:BaseViewModel/>
</Window.DataContext>

它工作正常,例如,当我在我的 ListView 中选择一个项目时,它会绑定并更新我的 MainWindow 中的 ImageView。

<ListView Background="Transparent"
          ItemsSource="{Binding ImageGridViewModel.Images}"
          SelectedItem="{Binding ImageGridViewModel.SelectedImage}">

然后它会像这样更新

    <Image Source="{Binding ImageGridViewModel.SelectedImage}"
           Margin="20">

完美无问题。

但是,我最近添加了第二个视图,即 Window,称为 WatermarkWindow,我设置了 DataContext,就像我在 MainWindow 中所做的那样,在 XAML 中也是这样。

<Window.DataContext>
    <viewModel:BaseViewModel/>
</Window.DataContext>

然后在新的Window 上绑定Image 控件

<Image Source="{Binding ImageGridViewModel.SelectedImage}"
       Margin="20">

但是当我打开那个窗口时,Image 控件的源没有绑定到属性,属性实际上返回NULL,我想我知道为什么会这样,我想这是因为在我的BaseViewModel 我是每次调用该 ViewModel 时都会实例化一个 new 实例。

我这样做的原因是因为我想实例化它的一个实例,以便我可以实际使用它来绑定东西。而不是它为空。

如果这不是问题所在,那么我仍然非常渴望了解和了解问题所在。 设置包含所有额外 ViewModel 的 BaseViewModel 的正确方法是什么?

public class BaseViewModel : ObservableObject
{
    public ImageGridViewModel ImageGridViewModel { get; set; } = new ImageGridViewModel();
}

还有 ObservableObject

public class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

这并不重要,因为我知道属性可以正常工作,这里是 ViewModel。

    public class ImageGridViewModel
    {
        public string ImagePath { get; set; }
        public string SelectedImage { get; set; }

        public ObservableCollection<string> Images { get; set; }
...

【问题讨论】:

  • 因此您希望两个视图使用相同的视图模型 instance。然后你不能在你的 XAML 代码中创建视图模型,而必须在其他地方设置 DataContext。
  • 你认为在哪里?我不想使用单例。
  • 根据我从您的问题中了解到的情况,您期望第二个窗口中的 ImageGridViewModel.SelectedImage 与第一个窗口中的相同。它不需要是单例,只要是同一个实例即可。
  • 是的,先生,我想知道如何访问同一个实例,因为每次在 BaseViewModel 中调用它时我都会实例化一个 new 实例
  • 是否有任何对象可以访问两个窗口实例?然后你可以在那里做类似window2.DataContext = window1.DataContext的事情。

标签: c# .net wpf mvvm data-binding


【解决方案1】:

我最终做的是将 DataContext 属性设置为 this,我在其中实例化了新的 WawtermarkWindow

if (wmw == null)
   {
       wmw = new WatermarkWindow();
       wmw.DataContext = this;
   }

【讨论】:

    猜你喜欢
    • 2021-04-22
    • 2019-01-03
    • 1970-01-01
    • 2023-03-11
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    • 1970-01-01
    相关资源
    最近更新 更多