摘要
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>
效果如下
二、使用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);
}
实现效果如下
三、总结
上面两种页面切换的方式,适合工程实践中需要设计单页面应用时使用。
源码地址https://github.com/cyberneo666/wpf_demo
原文地址:http://www.cnblogs.com/cyberneo666/p/16886949.html
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请务用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性