ToB企服应用市场:ToB评测及商务社交产业平台

标题: WPF多页面切换的实现方法 [打印本页]

作者: 怀念夏天    时间: 2022-11-13 21:17
标题: WPF多页面切换的实现方法
摘要

C/S端软件,左侧导航菜单+右侧页面切换的布局很常见。
这篇文章介绍下使用ContentControl控件和TabControl控件如何实现基础的页面切换。
一、使用ContentControl实现页面切换

页面使用UserControl来实现。
基于MVVM框架的思想,利用数据绑定机制,将控件集合绑定到ContentControl的数据源中。
ViewModel中定义UIElement类型变量和OpenPageCommand触发命令,代码如下:
  1. public  class MainViewModel:INotifyPropertyChanged
  2.     {
  3.         public event PropertyChangedEventHandler? PropertyChanged;
  4.         public Dictionary<string, UIElement> PageDict { get; set; } = new Dictionary<string, UIElement>();
  5.         public UIElement MainContent { get; set; }
  6.         public Command OpenPageCommand { get; set; }
  7.         public MainViewModel()
  8.         {
  9.             OpenPageCommand = new Command(OpenPage);
  10.         }
  11.         private void OpenPage(object o)
  12.         {
  13.             //反射创建
  14.             Type type=Assembly.GetExecutingAssembly().GetType("WpfApp1.Pages."+o.ToString());
  15.             //避免重复创建UIElement实例
  16.             if (!PageDict.ContainsKey(o.ToString()))
  17.             {
  18.                 PageDict.Add(o.ToString(), (UIElement)Activator.CreateInstance(type));
  19.             }
  20.             MainContent = PageDict[o.ToString()];
  21.             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MainContent"));
  22.         }
  23.         public void DoCloseCommand(object obj)
  24.         {
  25.             Pages.Remove(obj as PageModel);
  26.         }
  27.         public ObservableCollection<PageModel> Pages { get; set; } = new ObservableCollection<PageModel>();
  28.         public int PageSelectedIndex { get; set; }
  29.     }
复制代码
XAML中ContentControl绑定MainContent数据源,代码如下:
  1. <Grid>
  2.     <Grid.ColumnDefinitions>
  3.         <ColumnDefinition  Width="100"/>
  4.         <ColumnDefinition />
  5.         <ColumnDefinition />
  6.     </Grid.ColumnDefinitions>
  7.     <StackPanel Grid.Column="0">
  8.         <Button Content="pageA" Command="{Binding OpenPageCommand}" CommandParameter="PageA" />
  9.         <Button Content="pageB" Command="{Binding OpenPageCommand}" CommandParameter="PageB" />
  10.     </StackPanel>
  11.     <ContentControl Grid.Column="1" Content="{Binding MainContent}" >        
  12.     </ContentControl>   
  13. </Grid>
复制代码
效果如下

二、使用TabControl切换页面

TabControl控件可以在XAML中直接配置TabItem子控件,但是这种方式不适合工程实践。
更合理的方式是使用数据动态绑定的方式,来实现页面的切换。
TabItem样式改造

TabItem控件有Header属性,还有内容属性。其中Header属性默认为Text文本,实际应用中往往还需要关闭按钮,图标按钮等。
因此TabItem样式需要改造,以增加一个关闭按钮为例。
首先创建一个TabItem实体类PageModel.cs:
  1. public  class PageModel
  2.     {
  3.         public string Key { get; set; }
  4.         public string Text { get; set; }
  5.         public UIElement Content { get; set; }
  6.         public Command CloseCommand { get; set; }
  7.     }
复制代码
XAML中增加样式Resource
  1. <Window.Resources>
  2.         <StackPanel Orientation="Horizontal" x:Key="headerObject" x:Shared="False">
  3.             <TextBlock Text="{Binding Text}"/>
  4.             <Button Content="X" Command="{Binding CloseCommand}" CommandParameter="{Binding}" />
  5.         </StackPanel>
  6.         
  7.     </Window.Resources>
复制代码
XAML中TabControl调用:
  1. [/code]ViewModel中使用ObservableCollection集合作为TabItem数据集
  2. [code]    public ObservableCollection<PageModel> Pages { get; set; } = new ObservableCollection<PageModel>();
  3.     public int PageSelectedIndex { get; set; }
  4.     public MainViewModel()
  5.     {
  6.         OpenPageCommand = new Command(OpenPage);
  7.     }
  8.     private void OpenPage(object o)
  9.     {
  10.         Type type=Assembly.GetExecutingAssembly().GetType("WpfApp1.Pages."+o.ToString());
  11.         //避免重复创建实例
  12.         if (!Pages.ToList().Exists(x=>x.Text==o.ToString()))
  13.         {
  14.             Pages.Add(new PageModel() {
  15.                 Key = o.ToString(), Text = o.ToString(), Content = (UIElement)Activator.CreateInstance(type),
  16.                 CloseCommand=new Command(DoCloseCommand)
  17.             });
  18.         }
  19.         PageSelectedIndex = Pages.ToList().FindIndex(x => x.Text == o.ToString());
  20.         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("PageSelectedIndex"));
  21.     }
  22.     public void DoCloseCommand(object obj)
  23.     {
  24.         Pages.Remove(obj as PageModel);
  25.     }
复制代码
实现效果如下

三、总结

上面两种页面切换的方式,适合工程实践中需要设计单页面应用时使用。
源码地址https://github.com/cyberneo666/wpf_demo

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4