C# 正确分离视图和视图模型
我是初学者,在设置WPF项目和遵循MVVM模式方面有问题;我不知道如何将视图链接到具有以下组织的viewmodel: 我在名为“Company.App.UI”的项目根目录下设置了3个文件夹:Model、View和ViewModel。 App.xaml和MainWindow.xaml位于项目的根目录下 首先,我希望通过以下方式控制主窗口客户端区域中显示的内容: -将文件夹“View”中的渲染视图作为用户控件,例如“LoginView.xaml” -在文件夹“ViewModel”中具有相应的视图模型,例如“LoginView.xaml.cs” 然后我在MainWindow.xaml中所做的是:C# 正确分离视图和视图模型,c#,wpf,mvvm,C#,Wpf,Mvvm,我是初学者,在设置WPF项目和遵循MVVM模式方面有问题;我不知道如何将视图链接到具有以下组织的viewmodel: 我在名为“Company.App.UI”的项目根目录下设置了3个文件夹:Model、View和ViewModel。 App.xaml和MainWindow.xaml位于项目的根目录下 首先,我希望通过以下方式控制主窗口客户端区域中显示的内容: -将文件夹“View”中的渲染视图作为用户控件,例如“LoginView.xaml” -在文件夹“ViewModel”中具有相应的视图模型
<Window x:Class="Company.App.UI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewmodel="clr-namespace:Company.App.UI.ViewModel"
xmlns:view="clr-namespace:Company.App.UI.View" <!-- does not work, not a namespace -->
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate DataType="{x:Type viewmodel:LoginViewModel}">
<view:LoginView/> <!-- does not work -->
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<ContentControl Content="{Binding ClientArea}"/>
</StackPanel>
</Grid>
</Window>
在LoginView.xaml中更改以下内容:
x:Class="Company.App.UI.ViewModel.LoginViewModel"
对此
x:Class="Company.App.UI.ViewModel.LoginView"
因为这是一个控件而不是ViewModel
另外,LoginView.xaml.cs应该是这样的(没有看到您的实现):
使用System.Windows.Controls;
名称空间Company.App.UI.View
{
///
///LoginView.xaml的交互逻辑
///
公共部分类LoginView:UserControl
{
公共登录视图()
{
初始化组件();
}
}
}
当您掌握了窍门(mvvm)后,我建议您使用用于管道的(无需重新发明轮子)正是。。。。做伊戈尔告诉你的任何改变。 除此之外, 更改MainWindow.xaml.cs
if (_ClientArea == null) { ClientArea = new LoginViewModel(); }
到
根据我的理解,您只需要将一个标签从用户控件显示到主窗口,并学习MVVM概念。下面是对你的例子的解释,可能会对你有所帮助
<Grid>
<!--connect to viewmodel-->
<Grid.DataContext>
<viewmodel:LoginViewModel></viewmodel:LoginViewModel>
</Grid.DataContext>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--import user control-->
<view:LoginView Grid.Row="0"></view:LoginView>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<ContentControl Content="{Binding ClientArea}"/>
</StackPanel>
</Grid>
注意-在任何代码隐藏中尽量保持零代码。这是主要问题
MVVM的目的。它应该有
- 模型…(类文件,应该只包含属性)
- 查看…(usercontrols、xaml、窗口文件,其中应仅包含
xaml代码(零代码落后) - 模型视图。。。(类文件,其中应包含纯连接。) 在视图和模型之间,不应包含任何 视图或模型。它通过绑定进行连接)
如果你需要帮助,请告诉我。。。我有一些关于MVVM的示例演示项目 类似目的的帖子也帮助我得到了一些东西: , 这里有一个极好的主题: 在我发布我的问题后,我发现了另一个好的开始点(…): 基本上,我想要实现的是在一个窗口内管理内容区域,而不需要任何框架,更精确地管理“事务”,即在用户交互时从一个屏幕切换到另一个屏幕
感谢所有的评论,事情变得越来越清楚。文件夹结构与此无关。您必须在代码文件中使用适当的名称空间声明,例如,
namespace Company.App.UI.View{…}
“它工作”-什么不工作?您想要工作代码吗?ClientArea
被声明为UserControl
(非常糟糕的主意)。然后将名为LoginViewModel
的内容分配给它。什么是LoginViewModel
?它是viewmodel还是控件?要绑定到窗口的属性而不是窗口的DataContext
(保留为空)的属性,请使用相对源/祖先类型绑定:Content=“{binding clientrea,RelativeSource={RelativeSource AncestorType=window}”
要记住的基本规则。您的ViewModel不使用System.Windows.Controls代码>名称空间。我从上面的所有评论中看到了我的错误:错误是混淆了后面的xaml代码(.xaml.cs)和另一个.cs的viewmodel。我很高兴它有帮助!!1.
x:Class="Company.App.UI.ViewModel.LoginView"
using System.Windows.Controls;
namespace Company.App.UI.View
{
/// <summary>
/// Interaction logic for LoginView.xaml
/// </summary>
public partial class LoginView : UserControl
{
public LoginView()
{
InitializeComponent();
}
}
}
if (_ClientArea == null) { ClientArea = new LoginViewModel(); }
if (_ClientArea == null) { ClientArea = new LoginView(); }
<Grid>
<!--connect to viewmodel-->
<Grid.DataContext>
<viewmodel:LoginViewModel></viewmodel:LoginViewModel>
</Grid.DataContext>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--import user control-->
<view:LoginView Grid.Row="0"></view:LoginView>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<ContentControl Content="{Binding ClientArea}"/>
</StackPanel>
</Grid>