在上一篇文章中https://www.cnblogs.com/lizhiqiang0204/p/12367553.html我们使用按键Button来切换界面的,这次我们使用自定义的ItemsControl数据模板来切换页面。MainWindow.xaml如下

<Window.DataContext> <local:MainWindowVeiwModel></local:MainWindowVeiwModel> </Window.DataContext> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="200"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Border Grid.Column ="0" BorderThickness="3" BorderBrush="Gray" > <ScrollViewer Grid.Row="2"> <ItemsControl ItemsSource="{Binding Items}"> <ItemsControl.ItemTemplate> <DataTemplate> <Grid Style="{StaticResource MenuItemGrid}"> <Border MouseDown="UIElement_OnMouseDown" Style="{StaticResource MenuItem}" Background="{Binding BackColor}" > <TextBlock Grid.Row="0" Grid.Column="1" Style="{StaticResource H5}" Text="{Binding Title}"/> </Border> </Grid> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </ScrollViewer> </Border> <Border Grid.Column ="1" BorderBrush="Gray" BorderThickness="3" > <ContentPresenter Content="{Binding Content}"/> <!--使用内容呈现器来显示用户控件界面--> </Border> </Grid>
MainWindow.xaml.cs如下

public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e) { var sample = (SampleVm)((Border)sender).DataContext;//Border属于ItemsControl的其中一员,所以(Border)sender).DataContext 是MainWindowVeiwModel类成员Items数组中的其中一类(即SampleVm) var hvm = (MainWindowVeiwModel)DataContext;//MainWindow的数据上下文指定MainWindowVeiwModel类 hvm.Content = (UserControl)Activator.CreateInstance(sample.Content);//主页面MainWindow.xaml中的内容呈现器ContentPresenter指向选中Items数组中的UserControl句柄。 hvm.Items[hvm.SelectId].BackColor = new SolidColorBrush(Colors.Transparent);//把上一次选中的背景色改成透明色 hvm.Items[sample.Id].BackColor = new SolidColorBrush(Colors.Gray);//把这次选中的背景色改成灰色 hvm.SelectId = sample.Id;//已选择的ID改成本次选中的ID } }
MainWindow的DataContext上下文类MainWindowViewModel类如下

public class MainWindowVeiwModel : INotifyPropertyChanged { private UserControl _content; private SampleVm[] _Items; public int SelectId; public MainWindowVeiwModel()//在构造方法中向Items注册各个用户控件、id以及对应的标题 { _Items = new[] { new SampleVm("页面1", typeof(UserControl1),0), new SampleVm("页面2", typeof(UserControl2),1), }; } //ItemsControl中的数据模板绑定SampleVm类数组 public SampleVm[] Items { get { return _Items; } set { _Items = value; OnPropertyChanged("Items"); } } //主页面的内容呈现器 public UserControl Content { get { return _content; } set { _content = value; OnPropertyChanged("Content"); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
保存各个页面信息的类SampleVm如下

public class SampleVm : INotifyPropertyChanged { private SolidColorBrush _BackColor; public SampleVm(string title, Type content, int id) { Title = title; Content = content; Id = id; } public int Id { get; private set; } public string Title { get; set; } public Type Content { get; set; } public SolidColorBrush BackColor { get { return _BackColor; } set { _BackColor = value; OnPropertyChanged("BackColor"); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
App资源字典如下

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:UserControl_change_interface4"> <Style x:Key="Title" TargetType="TextBlock"> <Setter Property="HorizontalAlignment" Value="Center"></Setter> <Setter Property="Foreground" Value="#303030"></Setter> <Setter Property="TextAlignment" Value="Center"></Setter> <Setter Property="TextWrapping" Value="Wrap"></Setter> </Style> <Style x:Key="H3" TargetType="TextBlock" BasedOn="{StaticResource Title}"> <Setter Property="FontSize" Value="24"></Setter> </Style> <Style x:Key="H5" TargetType="TextBlock" > <Setter Property="FontSize" Value="20"></Setter> </Style> <Style x:Key="H6" TargetType="Label" > <Setter Property="Foreground" Value="Blue"></Setter> <Setter Property="FontSize" Value="30"></Setter> </Style> <Style x:Key="MenuItem" TargetType="Border"> <!--<Setter Property="Cursor" Value="Hand"></Setter>--> <Setter Property="Height" Value="50"></Setter> <Setter Property="BorderThickness" Value="0 1 0 1"></Setter> <Setter Property="BorderBrush" Value="#EBEBEB"></Setter> <!--<Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="WhiteSmoke"></Setter> </Trigger> </Style.Triggers>--> </Style> <Style x:Key="MenuItemGrid" TargetType="Grid"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="WhiteSmoke"></Setter> </Trigger> </Style.Triggers> </Style> </ResourceDictionary>
源码下载地址 https://github.com/lizhiqiang0204/UserControl-change-interface2_1
整体效果如下
MainWindowVeiwModel类中是直接引用UserControl1和UserControl2的,如果想在MainWindow.xaml.cs中访问修改UserControl1实体类类里面的成员,那只能访问在实体类成员前加static修饰,前面的例程中用户控件成员确实使用static修饰的。当然也可以在MainWindowVeiwModel类中实例化用户控件类,每次切换页面直接更改把主页面的内容呈现器ContentPresenter的Content指向MainWindowVeiwModel中实例化的成员就可以改变页面。该例程所有前台.xaml不变,所有后台.cs文件均有改变。

public partial class MainWindow : Window { public MainWindowVeiwModel MW; public MainWindow() { InitializeComponent(); MW = (MainWindowVeiwModel)DataContext;//MW就是MainWindowVeiwModel实体类 } private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e) { var sample = (SampleVm)((Border)sender).DataContext;//Border属于ItemsControl的其中一员,所以(Border)sender).DataContext 是MainWindowVeiwModel类成员Items数组中的其中一类(即SampleVm) MW.Content = MW.Items[sample.Id].User;//主页面MainWindow.xaml中的内容呈现器ContentPresenter指向选中Items数组中的UserControl句柄。 MW.Items[MW.SelectId].BackColor = new SolidColorBrush(Colors.Transparent);//把上一次选中的背景色改成透明色 MW.Items[sample.Id].BackColor = new SolidColorBrush(Colors.Gray);//把这次选中的背景色改成灰色 MW.SelectId = sample.Id;//已选择的ID改成本次选中的ID } private void btnClearCountClick(object sender, RoutedEventArgs e) { (MW.User1 as UserControl1).myStr = "0"; (MW.User1 as UserControl1).i = 0; (MW.User2 as UserControl2).myStr = "0"; (MW.User2 as UserControl2).i = 0; } }

public class MainWindowVeiwModel : INotifyPropertyChanged { private UserControl _content; public SampleVm[] _Items; public int SelectId; public UserControl User1 = new UserControl1(); public UserControl User2 = new UserControl2(); public MainWindowVeiwModel()//在构造方法中向Items注册各个用户控件、id以及对应的标题 { _Items = new[] { new SampleVm("页面1", User1,0), new SampleVm("页面2", User2,1), }; } //ItemsControl中的数据模板绑定SampleVm类数组 public SampleVm[] Items { get { return _Items; } set { _Items = value; OnPropertyChanged("Items"); } } //主页面的内容呈现器 public UserControl Content { get { return _content; } set { _content = value; OnPropertyChanged("Content"); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }

public class SampleVm : INotifyPropertyChanged { private SolidColorBrush _BackColor; public SampleVm(string title, Type content, int id) { Title = title; Content = content; Id = id; } public SampleVm(string title, UserControl user, int id) { Title = title; User = user; Id = id; } public int Id { get; private set; } public string Title { get; set; } public Type Content { get; set; } public UserControl User { get; set; } public SolidColorBrush BackColor { get { return _BackColor; } set { _BackColor = value; OnPropertyChanged("BackColor"); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }

public partial class UserControl1 : UserControl, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public int i = 0; private string _myStr = "0"; public string myStr //Label 标签内容绑定到这个myStr字符串 { get { return _myStr; } set { _myStr = value; OnPropertyChanged("myStr");//异步更新属性 } } public UserControl1() { InitializeComponent(); DataContext = this;//设置绑定数据的上下文为UserControl1类 } //累加按键处理事件 private void Button_Click(object sender, RoutedEventArgs e) { i++;//按一下数值累加一次 myStr = i.ToString();//把累加完后的数值转换成字符串赋给标签内容值(立刻更新标签内容) } }

public partial class UserControl2 : UserControl, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public int i = 0; private string _myStr = "0"; public string myStr //Label 标签内容绑定到这个myStr字符串 { get { return _myStr; } set { _myStr = value; OnPropertyChanged("myStr");//异步更新属性 } } public UserControl2() { InitializeComponent(); DataContext = this;//设置绑定数据的上下文为UserControl2类 } //累加按键处理事件 private void Button_Click(object sender, RoutedEventArgs e) { i++;//按一下数值累加一次 myStr = i.ToString();//把累加完后的数值转换成字符串赋给标签内容值(立刻更新标签内容) } }
源码下载地址https://github.com/lizhiqiang0204/UserControl-change-interface2_2
效果图如下