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 小时前
Unity 实战:用讯飞 WebAPI 做一个“说普通话、播方言“的语音程序
unity·c#·游戏引擎·语音识别
略略略咯咯3 小时前
C#Unity
开发语言·unity·c#
hh9503 小时前
gent Plan x DeepSeek Harness:多 Agent 协作场景下的中央编排实践
人工智能·wpf·adg·火山引擎·agent plan·adg成都社区
薛定猫AI5 小时前
OpenAI Codex本地完整配置教程|(Windows/Mac/Linux全平台,修复鉴权报错)
linux·windows·macos
Behavior5 小时前
Unity文字显示带竖线问题
c#·unity3d
w01_02_036 小时前
deepseek, harness , windows , 安装。
windows
辻弋2016 小时前
手动关服务会自动重启、组策略家庭版用不了——Windows Update Blocker用“禁用+锁定”双保险,让Win10/11自动更新彻底闭嘴
服务器·人工智能·windows·电脑·开源软件
qinwsq6 小时前
Gmssl windows下编译
windows·gmssl
qq_589666056 小时前
C语言、C++与C#的区别详解
c语言·c++·c#
明王明王7 小时前
Ubuntu 26.04 使用 Windows Spotlight:给 Bing Wallpaper 加上 Spotlight 支持
linux·windows·ubuntu