如果您从UserControl 中删除以下 sn-p 并按照我剩余的说明进行操作,我相信您会得到您想要的:
删除此
<UserControl.DataContext>
<viewModels:MyViewModel></viewModels:MyViewModel>
</UserControl.DataContext>
现在,假设您有一个 UserControl 或 Window 绑定到您希望在您的 UserControl 或 Window 中表示的 ViewModel。这样做的方法是在UserControl 或Window 中使用ContentControl,并在ResourceDictionary 中指定DataTemplate,如下所示:
.XAML:
<Window x:Class="WPF_Sandbox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:WpfApplication1.ViewModels"
Title="MainWindow"
x:Name="ThisControl">
<Window.DataContext>
<vm:MainWindowViewModel/>
</Window.DataContext>
<DockPanel LastChildFill="True">
<ContentControl DockPanel.Dock="Left" Content="{Binding NavigationRegion}"/>
<ContentControl DockPanel.Dock="Left" Content="{Binding ContentRegion}"/>
</DockPanel>
</Window>
ContentControl 将隐式查找与绑定到其Content 属性的ViewModel 关联的DataTemplate(在ResourceDictionary 对象的层次结构中)。假设我们将MainWindowViewModel 中的ContentRegion 属性设置为MyViewModel 的一个实例,如下所示:
MainWindowViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfApplication1.ViewModels
{
public class MainWindowViewModel : ViewModel
{
private object _navigationRegion;
private object _contentRegion;
public object NavigationRegion
{
get
{
return _navigationRegion;
}
set
{
_navigationRegion = value;
OnPropertyChanged(nameof(NavigationRegion));
}
}
public object ContentRegion
{
get
{
return _contentRegion;
}
set
{
_contentRegion = value;
OnPropertyChanged(nameof(ContentRegion));
}
}
public MainWindowViewModel()
{
ContentRegion = new MyViewModel(new MyModel());
}
}
}
你有一个ResourceDictionary,像这样指定:
MyResourceDictionary.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
xmlns:vm="clr-namespace:WpfApplication1.ViewModels"
xmlns:views="clr-namespace:WpfApplication1.Views">
<DataTemplate DataType="{x:Type vm:MyViewModel}">
<views:MyView/>
</DataTemplate>
</ResourceDictionary>
您已将您的ResourceDictionary 与您的Application.Resources 合并到您的 App.xaml 文件中,如下所示:
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MyResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
框架将为数据类型MyViewModel 隐式查找DataTemplate。框架将在我们指定的ResourceDictionary 中找到MyViewModel 的DataTemplate,并看到它应该由MyView 用户控件表示。此时框架将呈现MyView 用户控件。
为了子孙后代:
ViewModel.cs
using System.ComponentModel;
namespace WpfApplication1.ViewModels
{
public abstract class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected string _title;
protected string Title
{
get
{
return _title;
}
set
{
_title = value;
OnPropertyChanged(nameof(Title));
}
}
protected void OnPropertyChanged(string propName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
}
}
}