WPF中与MVVM的实例绑定
本文关键字:实例 绑定 MVVM 中与 WPF | 更新日期: 2023-09-27 18:30:02
我是WPF
和MVVM
模式的新手,对如何实现已有实例的data-binding
有点困惑。我知道MVVM
中有Model="business logic"
、ViewModel="presentation logic"
、View="actual presentation"
。
不幸的是,我目前无法弄清楚如何将视图绑定到ViewModel
和相应模型的现有实例。例如,我发现了这个MVVM教程,我很喜欢它,但它也只是创建了Model inside the ViewModel
。
那么,我该如何使用底层应用程序中先前实例化的模型呢?
EDIT:所以我正在一个小型测试项目中尝试Gusdor提出的方法,但无法使其发挥作用。我在App.xaml.cs中得到一个错误'WpfBindingTesting.App.MyViewModel' is a 'field', but used like a 'type'
(见下文)。我希望有人发现我做错了什么。这是我的代码:
ViewModel:
namespace WpfBindingTesting
{
class ViewModel
{
private List<string> names;
public List<string> Names
{
get { return names; }
set { names = value; }
}
public ViewModel()
{
Names = new List<string> { "string1", "string2", "string3" };
}
}
}
主窗口.xaml.cs:
namespace WpfBindingTesting
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
主窗口.xaml:
<Window x:Class="WpfBindingTesting.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
DataContext = "{Binding RelativeSource={RelativeSource Mode=Self}}"
>
<StackPanel>
<ListBox
ItemsSource="{Binding Path=Names}"
Height="50"
>
</ListBox>
</StackPanel>
</Window>
App.xaml.cs:
namespace WpfBindingTesting
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public App(){
MainWindow View = new MainWindow();
ViewModel MyViewModel = new ViewModel();
View.DataContext = MyViewModel; // this give error: 'WpfBindingTesting.App.MyViewModel' is a 'field', but used like a 'type'
//view.DataContext = new ViewModel();
//view.Show();
}
}
}
一般来说,我们将视图模型分配给视图的DataContext
属性。
只要有对视图的引用,就可以从代码中执行此操作。这是代码:
C夏普
Window view = new Window();
// add a view model
view.DataContext = new ViewModel() { Title = "View Model 1" };
view.Show();
// add another view model to demonstrate the binding
view.DataContext = new ViewModel() { Title = "View Model 2" };
XAML
窗口的XAML可能如下所示。
<Window Title={Binding Title}>
</Window>
注意到Source
或ElementName
属性在绑定声明中是如何保持未指定的?这指示绑定使用当前DataContext
作为源。
模型=业务
View=用户看到了什么,实际上与逻辑无关(这当然是一个谎言,但这正是您所追求的)
ViewModel=是什么将它们粘合在一起。正是您的适配器为视图提供了您所拥有的模型所需的信息。
我建议你看看MVVM平台(比如MVVM Light),它在你开始时为你提供了很多你需要"免费"做的事情。
作为指南,这里有3个选项可以进行绑定:
-
1.1在XAML上,设置
DataContext = "{Binding relativeSource={RelativeSource self}}
1.2对代码隐藏(您的xaml.cs)具有属性
1.3在构造函数中初始化属性BEFORE theInitializeComponent()
。 -
2.1 XAML上的Igonre
DataContext
2.2在后面的代码中,从InitializeComponent();
开始2.3在构造函数中具有类似DataContext = this;
的行2.4初始化您的属性 -
3.1给窗口或UserControl一个名称:
Name = "MyWindow"
(在xaml中)3.2绑定到元素:ItemSource={Binding ElementName = MyWindow, path =... }"
3.3在构造函数中初始化属性BEFORE theInitializeComponent()
。
最后但并非最不重要的一点是,看看我的文章"The Big MVVM Template",你可以按照它来做,它会让你很好地掌握基本知识,此外,你还会有一个完整的文档示例:)。
您的问题更多的是关于设计,而不是编码。我认为,如果您已经有视图模型的现有实例,并且只想在新视图中重用/重新分配它们。然后你可能需要看一下IOCContainers(因为实际上你想在这里进行某种依赖注入)
简单地说,使用IOC容器来维持viewModel的使用寿命。根据您的需要配置容器以提供所需的ViewModel,即新对象或现有视图模型对象。
Unity集装箱
在统一容器中,您可以注册您的对象,并在将来根据需要解析它们。使用以下语法简化:
寄存器:
1.MyUnityConatiner.RegisterInstance<IMyService>(myDataService);
or
2.MyContainer.RegisterInstance<IMyService>("Email", myEmailService);
解决:
1.MyUnityConatiner.Resolve<IMyService>();
or
2.MyConatiner.Resolve<IMyService>("Email");
我知道这在你看来是一个有点偏离的解决方案,但如果你学会使用它,你会对你的问题以及如何重用对象(模型/viewmodel)有不同的看法。