WPF常用技巧-原生子窗口嵌套/切换

在没有使用MVVM框架导航功能的情况下,要实现子窗口在主窗口的嵌套,可以通过在主窗口中使用ContentControl容器控件来完成,子窗口使用用户控件来构建,然后作为内容放入到主窗口的ContentControl中就OK了。

创建导航栏模型

csharp 复制代码
public class MenuModel
{
    //导航标题
    public string ManuTitle { get; set; }
    //导航所对应的用户控件路径,例如WPFExample.Views.FirstPage
    public string TargetView { get; set; }
}

创建主窗口模型

csharp 复制代码
public class MainModel : INotifyPropertyChanged
{
    //导航列表
    public List<MenuModel> MenuList { get; set; } = new List<MenuModel>();
    //嵌入的子窗口的标题
    public string PageTitle { get; set; }
    //嵌入的子窗口对象
    private object _page;
    public object Page {
        get => _page; 
        set { 
            _page = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Page"));
        } 
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

创建命令基础类型

csharp 复制代码
public class CommandBase : ICommand
{
    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public Action<object> DoExecute { get; set; }
    public void Execute(object parameter)
    {
        DoExecute?.Invoke(parameter);
    }
}

创建主窗口的视图模型

在主窗口视图模型中定义窗口的一些业务逻辑处理、主窗口模型的创建及初始化。

csharp 复制代码
internal class MainViewModel
{
    public MainModel MainModel { get; set; }

    public MainViewModel()
    {
        MainModel = new MainModel();
        MainModel.MenuList.Add(new MenuModel
        {
            ManuTitle = "第一个子窗口",
            TargetView="WPFExample.Views.FirstUserControl"
        });
        MainModel.MenuList.Add(new MenuModel
        {
            ManuTitle = "第二个子窗口",
            TargetView = "WPFExample.Views.SecondUserControl"
        });

        //默认显示第一个子窗口
        MainModel.PageTitle = MainModel.MenuList[0].ManuTitle;
        ShowPage(MainModel.MenuList[0].TargetView);
    }
    public void ShowPage(string targetView)
    {
        Type type = GetType().Assembly.GetType(targetView);
        MainModel.Page = Activator.CreateInstance(type);
    }

    public CommandBase GuideCommand
    {
        get
        {
            return new CommandBase
            {
                DoExecute = obj =>
                {
                    Type type = GetType().Assembly.GetType(obj.ToString());
                    MainModel.Page = Activator.CreateInstance(type);
                }
            };
        }
    }

}

在xaml中使用

xml 复制代码
<Window ......
        xmlns:vm="clr-namespace:WPFExample.ViewModels"
        ......>
    <Window.DataContext>
        <vm:MainViewModel/>
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="4*"/>
        </Grid.ColumnDefinitions>
        <ItemsControl ItemsSource="{Binding MainModel.MenuList}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding ManuTitle}" Tag="{Binding TargetView}" Height="40" Width="100"
                            Command="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext.GuideCommand}"
                            CommandParameter="{Binding TargetView}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Columns="1" >
                        
                    </UniformGrid>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
        <ContentControl Grid.Row="0" Grid.Column="1" Content="{Binding MainModel.Page}" Name="cc"/>
		</Grid>
</Window>
相关推荐
界面开发小八哥2 小时前
界面组件DevExpress WPF中文教程:Grid - 如何检查节点?
ui·.net·wpf·界面控件·devexpress·ui开发
钢铁男儿5 小时前
C#接口实现详解:从理论到实践,掌握面向对象编程的核心技巧
java·前端·c#
神所夸赞的夏天6 小时前
c#获取Datatable中某列最大或最小的行数据方法
开发语言·c#
我是唐青枫7 小时前
C#.NET serilog 详解
开发语言·c#·.net
future14127 小时前
项目开发日记
前端·学习·c#·游戏开发
ljh5746491198 小时前
Airtest 的 Poco 框架中,offspring()
windows
我是苏苏16 小时前
C#基础:Winform桌面开发中窗体之间的数据传递
开发语言·c#
斜月三18 小时前
windows部署多实例filebeat监控相同路径下文件
windows·filebeat
尽兴-21 小时前
如何将多个.sql文件合并成一个:Windows和Linux/Mac详细指南
linux·数据库·windows·sql·macos
水果里面有苹果1 天前
20-C#构造函数--虚方法
java·前端·c#