如图样:

View结构

MainView(MainViewModel)
|---Guide1View(Guide1ViewModel)
|---Guide2View(Guide2ViewModel)
  |---Guide2_1View1(Guide2_1ViewModel)
  |---Guide2_1View2(Guide2_1ViewModel)

ViewModel实例结构

Main(ViewModelViewModel)
|---CurrentViewModel(GuidePageViewModelBase)
|---PageViewModelList(ObservableCollection<GuidePageViewModelBase>)
  |---Guide1(Guide1ViewModel)
  |---Guide2(Guide2ViewModel)
    |---LVM1(LViewModel)
    |---LVM2(LViewModel)

1、通过ContentControl显示选中的视图模型对应的视图:

<ContentControl Content="{Binding CurrentViewModel}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type viewmodel:Guide1ViewModel}">
<view:Guide1View/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodel:Guide2ViewModel}">
<view:Guide2View/>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>

2、Guide2_1View作为一个多次使用的控件,对应一个LViewModel,设置自己的DataContext(这里的背景是该视图的使用个数确定的。当然也可以用ListBox代替):

<view:Guide2_1View DataContext="{Binding Path=DataContext.LVM1,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<view:Guide2_1View DataContext="{Binding Path=DataContext.LVM2,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />

完整代码:

ViewModel:

using GalaSoft.MvvmLight;

namespace WPF_NestedVMAndView.ViewModel
{
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
PageViewModelList = new ObservableCollection<GuidePageViewModelBase>()
{
new Guide1ViewModel(),
new Guide2ViewModel(),
};
CurrentViewModel = PageViewModelList[];
} public const string CurrentViewModelPropertyName = "CurrentViewModel";
private GuidePageViewModelBase _currentViewModel;
public GuidePageViewModelBase CurrentViewModel
{
get
{
return _currentViewModel;
} set
{
if (_currentViewModel == value)
return; _currentViewModel = value;
RaisePropertyChanged(CurrentViewModelPropertyName);
}
} public const string PageViewModelListPropertyName = "PageViewModelList";
private ObservableCollection<GuidePageViewModelBase> _pageViewModelList;
public ObservableCollection<GuidePageViewModelBase> PageViewModelList
{
get
{
return _pageViewModelList;
} set
{
if (_pageViewModelList == value)
return; _pageViewModelList = value;
RaisePropertyChanged(PageViewModelListPropertyName);
}
}
} public class GuidePageViewModelBase : ViewModelBase
{
public GuidePageViewModelBase(string name)
{
Name = name;
} public const string NamePropertyName = "Name";
private string _name;
public string Name
{
get
{
return _name;
} set
{
if (_name == value)
return; _name = value;
RaisePropertyChanged(NamePropertyName);
}
}
} public class Guide1ViewModel : GuidePageViewModelBase
{
public Guide1ViewModel()
: base("Guide1")
{ }
} public class Guide2ViewModel : GuidePageViewModelBase
{
public Guide2ViewModel() : base("Guide2")
{
LVM1 = new LViewModel()
{
Text = "LVM1",
};
LVM2 = new LViewModel()
{
Text = "LVM2",
};
} public const string LVM1PropertyName = "LVM1";
private LViewModel _lvm1;
public LViewModel LVM1
{
get
{
return _lvm1;
} set
{
if (_lvm1 == value)
return; _lvm1 = value;
RaisePropertyChanged(LVM1PropertyName);
}
} public const string LVM2PropertyName = "LVM2";
private LViewModel _lvm2;
public LViewModel LVM2
{
get
{
return _lvm2;
} set
{
if (_lvm2 == value)
return; _lvm2 = value;
RaisePropertyChanged(LVM2PropertyName);
}
}
} public class LViewModel : ViewModelBase
{
public const string TextPropertyName = "Text";
private string _text;
public string Text
{
get
{
return _text;
} set
{
if (_text == value)
return; _text = value;
RaisePropertyChanged(TextPropertyName);
}
}
}
}

MainView:

<Window x:Class="WPF_NestedVMAndView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:view="clr-namespace:WPF_NestedVMAndView.View"
xmlns:viewmodel="clr-namespace:WPF_NestedVMAndView.ViewModel"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding Main,Source={StaticResource Locator}}">
<DockPanel Margin="20">
<ListBox ItemsSource="{Binding PageViewModelList}" DisplayMemberPath="Name" SelectedItem="{Binding CurrentViewModel}" DockPanel.Dock="Left" Width="100"/>
<ContentControl Content="{Binding CurrentViewModel}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type viewmodel:Guide1ViewModel}">
<view:Guide1View/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodel:Guide2ViewModel}">
<view:Guide2View/>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</DockPanel>
</Window>

Guide1View:

<UserControl x:Class="WPF_NestedVMAndView.View.Guide1View"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Background="White"
>
<Grid>
<TextBlock Text="{Binding Name}" Margin="10"/>
</Grid>
</UserControl>

Guide2View:

<UserControl x:Class="WPF_NestedVMAndView.View.Guide2View"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:view="clr-namespace:WPF_NestedVMAndView.View"
mc:Ignorable="d"
Background="White">
<DockPanel>
<TextBlock Text="{Binding Name}" Margin="10" DockPanel.Dock="Top"/>
<view:Guide2_1View DataContext="{Binding Path=DataContext.LVM1,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" DockPanel.Dock="Top"/>
<view:Guide2_1View DataContext="{Binding Path=DataContext.LVM2,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" DockPanel.Dock="Top"/>
</DockPanel>
</UserControl>

Guide2_1View:

<UserControl x:Class="WPF_NestedVMAndView.View.Guide2_1View"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Background="White">
<Grid>
<TextBlock Text="{Binding Text}" Margin="10"/>
</Grid>
</UserControl>

WPF中模板选择和DataContext的一些使用的更多相关文章

  1. WPF中如何选择合适的元数据标记?(英文)

    原文:WPF中如何选择合适的元数据标记?(英文) FrameworkPropertyMetadataOptions Enumeration:Specifies the types of framewo ...

  2. 总结:WPF中模板需要绑定父级别的ViewModel该如何处理

    原文:总结:WPF中模板需要绑定父级别的ViewModel该如何处理 <ListBox ItemsSource="{Binding ClassCollection}"> ...

  3. WPF动态模板选择的两种实现

    前言 .net开发工作了六年,看了大量的博客,现在想开始自己写博客,这是我的第一篇博客,试试水,就从自己最常使用的WPF开始. 今天我来给大家分享可用户动态选择控件模板的两种实现方式:DataTrig ...

  4. WPF中 ItemsSource 和DataContext不同点

    此段为原文翻译而来,原文地址 WPF 中 数据绑定 ItemSource和 DataContext的不同点: 1.DataContext 一般是一个非集合性质的对象,而ItemSource 更期望数据 ...

  5. WPF中的数据模板使用方式之一:ContentControl、ContentTemplate和TemplateSelector的使用

    在WPF中,数据模板是非常强大的工具,他是一块定义如何显示绑定的对象的XAML标记.有两种类型的控件支持数据模板:(1)内容控件通过ContentTemplate属性支持数据模板:(2)列表控件通过I ...

  6. wpf 获取datagrid中模板中控件

    //获取name为datagrid中第三列第一行模板的控件 FrameworkElement item = dataGrid.Columns[].GetCellContent(dataGrid.Ite ...

  7. 关于WPF中ItemsControl系列控件中Item不能继承父级的DataContext的解决办法

    WPF中所有的集合类控件,子项都不能继承父级的DataContext,需要手动将绑定的数据源指向到父级控件才可以. <DataGridTemplateColumn Header="操作 ...

  8. WPF 中获取DataGrid 模板列中控件的对像

    WPF 中获取DataGrid 模板列中控件的对像 #region 当前选定行的TextBox获得焦点 /// <summary> /// 当前选定行的TextBox获得焦点 /// &l ...

  9. 在WPF中使用文件夹选择对话框

    开发中有时会想实现"选择某个文件夹"的效果: 在WPF中,使用Microsoft.Win32.OpenFileDialog只能选择文件,FolderBrowserDialog只能用 ...

随机推荐

  1. 一些java面试题

    1.SQL中的having子句用来干啥的? 答:having子句的功能是进行分组(GROUP BY)后的过滤 如:select id,avg(score) from  表 group by 学号 ha ...

  2. JDK版本不兼容问题之:一台机器安装多个版本的JDK

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://guojie.blog.51cto.com/59049/45964 我的机器上最开 ...

  3. 聊聊 App Store 的产品和推广运营攻略

    在这个工匠的时代,越来越多开发者投入了手机应用的开发圈子.如何才能在激烈的竞争中脱颖而出,少走弯路呢?我们跟空中网负责iPhone游戏的运营和推广的洪亮进行了一次交流,得到了不少经验和诀窍,值得分享给 ...

  4. Linux系统中CPU使用率查询常用的5个命令

    在程序开发中,我们一般都是在Linux系统上进行开发,因此对Linux系统的维护工作很重要.在Linux系统维护中,我们需要经常查看的就是cpu的使用率,分析系统的整体运行情况.那CPU使用率怎么查询 ...

  5. 爬虫神器xpath的用法(一)

    1.如果你没有安装lxml,请运行pip install lxml或者easy_install lxml安装,如果在安装过程中失败的话, 是因为lxml需要依赖某些库文件,具体可以问下度娘,这里不再赘 ...

  6. 大型架构.net平台篇(WEB层均衡负载nginx)

    第一部分 WEB层均衡负载.net平台下,我目前部署过的均衡负载有两种方式(iis7和Nginx),以下以Nginx为例讲解web层的均衡负载. 简介:Nginx 超越 Apache 的高性能和稳定性 ...

  7. 【Vegas原创】安装rhel6.2,不能进图形化界面的终极解决方法

    安装的时候,千万不要一路下一步,you should know,linux不是windows那么的傻瓜.   方法一: 在倒数最后一步,选择Desktop,而千万不要下一步,默认选择Basic Ser ...

  8. 单点登录 SSO(Single Sign-On)的实现原理

    为什么要 SSO? 企业的信息化过程是一个循序渐进的过程,这就造成在企业的不同时期,根据业务和发展需要,构建了多个应用程序,而这些应用程序在功能.设计和技术可能都有所不同,就形成了各自独立的用户库和用 ...

  9. 100+诡异的数据集,20万Eclipse Bug、死囚遗言等

    摘要:近日,Robert Seaton整理了100多个最有趣的数据集,其中包括Jeopardy真题,死囚的最后一句话,20万个Eclipse Bug,足球比赛相关,柏拉图式的爱情,太阳系以外的行星,1 ...

  10. cer pfx格式数字证书区别

    作为文件形式存在的证书一般有这几种格式: 1.带有私钥的证书 由Public Key Cryptography Standards #12,PKCS#12标准定义,包含了公钥和私钥的二进制格式的证书形 ...