我是初学者,在设置WPF项目和遵循MVVM模式时遇到问题;我没有看到如何将视图链接到viewmodel与下面的组织:
我在名为“Company.App.UI”的项目的根目录中设置了3个文件夹:Model,View和ViewModel。 App.xaml和MainWindow.xaml是项目的根源。
从这开始,我希望通过以下方式控制MainWindow客户区中显示的内容: - 将“View”文件夹中的渲染视图作为UserControls,例如“LoginView.xaml” - 在“ViewModel”文件夹中具有相应的视图模型,例如“LoginView.xaml.cs”
然后我在MainWindow.xaml中所做的是:
<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>
在MainWindow.xaml.cs:
using System.Windows;
using System.Windows.Controls;
using Company.App.UI.ViewModel;
namespace Company.App.UI
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private UserControl _ClientArea = null;
public UserControl ClientArea
{
get { return _ClientArea; }
set { _ClientArea = value; }
}
public MainWindow()
{
if (_ClientArea == null) { ClientArea = new LoginViewModel(); }
InitializeComponent();
}
}
}
LoginView是一个带有一个Label的简单UserControl,只是为了看它是什么。 如果我将LoginView.xaml放在项目的根目录下,在MainWindow.xaml旁边,它可以工作...... 我做错了什么/错过了什么? 我不想使用任何框架(PRISM等)来实现这一点。 如果我的帖子是重复但我在搜索时也找不到它,我很抱歉。 谢谢,
我使用VS2013和0更新/补丁/等 一切都在同一个项目中。
错误输出是:
LoginView.xaml:
<UserControl x:Class="Company.App.UI.ViewModel.LoginViewModel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Label>User control login</Label>
</Grid>
</UserControl>
LoginViewModel.cs:
using System.Windows.Controls;
namespace Company.App.UI.ViewModel
{
public partial class LoginViewModel : UserControl
{
public LoginViewModel()
{
}
}
}
答案 0 :(得分:0)
在 LoginView.xaml 中更改此内容:
x:Class="Company.App.UI.ViewModel.LoginViewModel"
到这个
x:Class="Company.App.UI.ViewModel.LoginView"
因为这是一个控件而不是ViewModel
此外, LoginView.xaml.cs 应该是这样的(没有看到您的实现):
using System.Windows.Controls;
namespace Company.App.UI.View
{
/// <summary>
/// Interaction logic for LoginView.xaml
/// </summary>
public partial class LoginView : UserControl
{
public LoginView()
{
InitializeComponent();
}
}
}
当你掌握它的时候(mvvm)我会建议使用mvvm light toolkit来管道(没有必要重新发明轮子)
答案 1 :(得分:0)
完全......做任何改变伊戈尔告诉你的事。 与此同时,
更改您的MainWindow.xaml.cs
if (_ClientArea == null) { ClientArea = new LoginViewModel(); }
到
if (_ClientArea == null) { ClientArea = new LoginView(); }
另外根据我的理解,你只想从用户控件到主窗口显示一个标签,并想学习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的目的。它应该只有
我也不知道你创建'ClientArea'的目的是什么......你在某个地方定义了它的内容吗? 如果您需要任何帮助,请告诉我......我在MVVM上有一些示例演示项目。
答案 2 :(得分:0)
具有类似目的的帖子也帮助我做事:
Binding a ContentControl to UserControl, and reuse same instance,
这里有一个很好的主题:How to preserve the full state of the View when navigating between Views in an MVVM application?。
在我发布问题(...)之后发现的另一个好处:https://msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx
基本上我想要实现的是在一个窗口内管理内容区域,而不管任何框架,更精确地管理“交易”,即在用户交互时从一个屏幕切换到另一个屏幕。
感谢所有评论,事情越来越清晰。