c# - 具有 wpf 视图的类库的 2 个视图(相同实例)的 1 个 ViewModel
问题描述
请耐心等待,因为我对这一切还很陌生。我目前正在尝试将我的两个视图绑定到我的 ViewModel 的同一个实例(在 xaml 中不是代码隐藏)。我的代码用于软件中的插件(输出是类库 .dll 文件),因此它没有设置为 C# WPF 应用程序(我没有 App.xaml)。我已经研究过使用 MVVM light、viewmodellocator 和在线找到的所有其他解决方案,但它们都依赖于 App.xaml,我不确定如何在我的情况下实现。
根据我正在为其开发插件的软件文档;入口点是一个特定的类(现在称之为 EntryPoint.cs)。Main 方法用于进入。在我的 Main 方法中,我创建了 MainView。
入口点.cs:
public class EntryPoint
{
private MainView _MyForm;
public void Main(...)
{
....
_MyForm = new MainView();
_MyForm.ShowDialog();
}
}
在我的主视图构造函数中,我启动了我的 MainWindowViewModel。
Mainview.cs:
public partial class MainView : Window
{
public MainView()
{
InitializeComponent();
this.DataContext = new MainWindowViewModel();
}
}
SecondView 由我的 MainView 上的按钮打开,如下所示;这是来自我的 MainWindowViewModel 的代码片段,其中包含打开我的 SecondView 的命令:
public void OpenSecondView()
{
....
SecondView newView = new SecondView (this);
SecondView.Show();
}
我之前通过在我的 SecondView 的构造函数中将视图模型作为参数传递来在我的代码隐藏中设置数据上下文:
public partial class SecondView: Window
{
public SecondView(MainViewModel viewModel)
{
InitializeComponent();
this.DataContext = viewModel;
}
}
如何在我的 xaml 中实现这一点?我想绑定到我的 viewModel 的同一个实例。有什么指导吗?
解决方案
试试这个:
主视图.cs
public partial class MainView : Window
{
public MainView()
{
InitializeComponent();
var vm = new MainWindowViewModel();
vm.PropertyChanged += OnViewModelPropertyChanged;
this.DataContext = vm;
}
public void OnViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof("OpenSecondViewCommand")
{
SecondView newView = new SecondView() { DataContext = this.DataContext };
SecondView.Show();
}
}
MainWindowViewModel.cs
// Get rid of your OpenSecondView() method that is tied to your Command. It is too tightly-
// coupled with the View. Instead, just use your Command public property and trigger the
// PropertyChanged event, then let the View layer deal with what happens when you trigger
// this Command. I don't know the name of your Command public property so I'm just going
// to assume it's called OpenSecondViewCommand. Something like this would suffice:
private RelayCommand openSecondViewCommand;
public RelayCommand OpenSecondViewCommand
{
get
{
if (this.openSecondViewCommand == null)
this.openSecondViewCommand = new RelayCommand(() => PropertyChanged?.Invoke(this, new PropertyEventArgs(nameof(OpenSecondViewCommand)));
return this.openSecondViewCommand;
}
}
第二视图.cs
// Remove the MainWindowViewModel parameter from your c'tor.
// Change it back to the way it was originally.
public partial class SecondView: Window
{
public SecondView()
{
InitializeComponent();
}
}
详细说明
MVVM 设计模式的主要方面之一是通过将模型与视图模型以及视图模型与视图分离和解耦来定义“关注点分离”。此设计模式以这种方式定义它,以便您可以用新的 UI 替换整个 UI,而无需接触您的 ViewModel 代码。在您的情况下,您已将您的嵌入SecondView
到您的MainWindowViewModel
. 这违反了 MVVM 设计模式。
将两个 View 绑定到同一个 ViewModel 就像确保两个 View 具有相同的DataContext
. 您可以看到我已经MainView.cs
通过将SecondView
DataContext
属性设置为MainView
DataContext
.
SecondView newView = new SecondView() { DataContext = this.DataContext };
推荐阅读
- mongodb - Mongoose:findByIdAndUpdate() 如何根据现有数据有条件地更新?
- python - 在两个 h2 标签之间具有以下兄弟的 Scrapy xpath
- java - 在 Minecraft 1.12.2 中制作盔甲套装作为套装奖励提供健康提升
- php - MySQL查找不同数量和价格的商品的总销售额
- python - 如何在python函数中打印值?
- tesseract - 为什么 tesseract 不会在图像中找到这个简单的文本?
- python - Keras:验证数据未显示准确性
- php - 使用第一个选择框值从数据库中触发/过滤第二个选择框的数据
- flutter - 颤振:错误:找不到 pubspec.yaml 文件
- java - 为什么 onCreate(Bundle savedInstanceState) 不访问 onSaveInstanceState() Bundle?