WPF多页面切换的实现方法

  • WPF多页面切换的实现方法已关闭评论
  • 241 次浏览
  • A+
所属分类:.NET技术
摘要

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


摘要

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

一、使用ContentControl实现页面切换

页面使用UserControl来实现。

基于MVVM框架的思想,利用数据绑定机制,将控件集合绑定到ContentControl的数据源中。

ViewModel中定义UIElement类型变量和OpenPageCommand触发命令,代码如下:

public  class MainViewModel:INotifyPropertyChanged     {         public event PropertyChangedEventHandler? PropertyChanged;         public Dictionary<string, UIElement> PageDict { get; set; } = new Dictionary<string, UIElement>();         public UIElement MainContent { get; set; }         public Command OpenPageCommand { get; set; }         public MainViewModel()         {             OpenPageCommand = new Command(OpenPage);         }         private void OpenPage(object o)         {             //反射创建             Type type=Assembly.GetExecutingAssembly().GetType("WpfApp1.Pages."+o.ToString());             //避免重复创建UIElement实例             if (!PageDict.ContainsKey(o.ToString()))             {                 PageDict.Add(o.ToString(), (UIElement)Activator.CreateInstance(type));             }             MainContent = PageDict[o.ToString()];             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MainContent"));         }         public void DoCloseCommand(object obj)         {             Pages.Remove(obj as PageModel);         }         public ObservableCollection<PageModel> Pages { get; set; } = new ObservableCollection<PageModel>();         public int PageSelectedIndex { get; set; }     }  

XAML中ContentControl绑定MainContent数据源,代码如下:

<Grid>     <Grid.ColumnDefinitions>         <ColumnDefinition  Width="100"/>         <ColumnDefinition />         <ColumnDefinition />     </Grid.ColumnDefinitions>     <StackPanel Grid.Column="0">         <Button Content="pageA" Command="{Binding OpenPageCommand}" CommandParameter="PageA" />         <Button Content="pageB" Command="{Binding OpenPageCommand}" CommandParameter="PageB" />     </StackPanel>     <ContentControl Grid.Column="1" Content="{Binding MainContent}" >             </ContentControl>     </Grid> 

效果如下

WPF多页面切换的实现方法

二、使用TabControl切换页面

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

TabItem样式改造

TabItem控件有Header属性,还有内容属性。其中Header属性默认为Text文本,实际应用中往往还需要关闭按钮,图标按钮等。

因此TabItem样式需要改造,以增加一个关闭按钮为例。

首先创建一个TabItem实体类PageModel.cs:

public  class PageModel     {         public string Key { get; set; }         public string Text { get; set; }         public UIElement Content { get; set; }         public Command CloseCommand { get; set; }     } 

XAML中增加样式Resource

 <Window.Resources>         <StackPanel Orientation="Horizontal" x:Key="headerObject" x:Shared="False">             <TextBlock Text="{Binding Text}"/>             <Button Content="X" Command="{Binding CloseCommand}" CommandParameter="{Binding}" />         </StackPanel>         <Style TargetType="TabItem">             <Setter Property="Header" Value="{StaticResource headerObject}"/>             <Setter Property="Content" Value="{Binding Content}"/>         </Style>     </Window.Resources> 

XAML中TabControl调用:

<TabControl Grid.Column="2" ItemsSource="{Binding Pages}" SelectedIndex="{Binding PageSelectedIndex}"> </TabControl> 

ViewModel中使用ObservableCollection集合作为TabItem数据集

    public ObservableCollection<PageModel> Pages { get; set; } = new ObservableCollection<PageModel>();     public int PageSelectedIndex { get; set; }     public MainViewModel()     {         OpenPageCommand = new Command(OpenPage);     }     private void OpenPage(object o)     {         Type type=Assembly.GetExecutingAssembly().GetType("WpfApp1.Pages."+o.ToString());         //避免重复创建实例         if (!Pages.ToList().Exists(x=>x.Text==o.ToString()))         {             Pages.Add(new PageModel() {                 Key = o.ToString(), Text = o.ToString(), Content = (UIElement)Activator.CreateInstance(type),                 CloseCommand=new Command(DoCloseCommand)             });         }         PageSelectedIndex = Pages.ToList().FindIndex(x => x.Text == o.ToString());         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("PageSelectedIndex"));     }     public void DoCloseCommand(object obj)     {         Pages.Remove(obj as PageModel);     } 

实现效果如下

WPF多页面切换的实现方法

三、总结

上面两种页面切换的方式,适合工程实践中需要设计单页面应用时使用。

源码地址https://github.com/cyberneo666/wpf_demo