You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WPF点击窗体内嵌页面按钮隐藏当前窗口打开新窗口问题

WPF 内嵌页面按钮点击隐藏宿主窗口实现方案

问题场景

现有WPF窗体使用DockPanel承载Page实现导航功能,需求为点击内嵌Page上的按钮时,隐藏当前宿主窗口、弹出新窗口,原有实现代码未生效。
问题相关代码截图

原有问题代码

Page端按钮代码

public partial class SubPnlItems_SK : Page
{
    public SubPnlItems_SK()
    {
        InitializeComponent();
    }

    private void btnAddItems_SK_Click(object sender, RoutedEventArgs e)
    {
        PnlTabMenu_SK tabMenu_SK = new PnlTabMenu_SK();
        PnlAddItem_SK pnlAddItem_SK = new PnlAddItem_SK();
        tabMenu_SK.Visibility = Visibility.Hidden;
        pnlAddItem_SK.ShowDialog();

    }

    private void btnViewItems_SK_Click(object sender, RoutedEventArgs e)
    {

    }
}

宿主窗口代码

public partial class PnlTabMenu_SK : Window
{
    public PnlTabMenu_SK()
    {
        InitializeComponent();
        dockPanel_SK.NavigationService.Navigate(new Uri("SubPnlItems_SK.xaml", UriKind.Relative));
    }

    private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        this.DragMove();
    }

    private void btn_minimize_Click(object sender, RoutedEventArgs e)
    {
        WindowState = WindowState.Minimized;
    }

    private void btn_close_Click(object sender, RoutedEventArgs e)
    {
        this.Close();
    }

    private void btnItems_SK_Click(object sender, RoutedEventArgs e)
    {
        dockPanel_SK.NavigationService.Navigate(new Uri("SubPnlItems_SK.xaml", UriKind.Relative));

    }

    private void btnISN_SK_Click(object sender, RoutedEventArgs e)
    {
        dockPanel_SK.NavigationService.Navigate(new Uri("SubPnlISN_SK.xaml", UriKind.Relative));
    }

    private void btnMRF_SK_Click(object sender, RoutedEventArgs e)
    {
        dockPanel_SK.NavigationService.Navigate(new Uri("SubPnlMRF_SK.xaml", UriKind.Relative));
    }

    private void btnGRN_SK_Click(object sender, RoutedEventArgs e)
    {
        dockPanel_SK.NavigationService.Navigate(new Uri("SubPnlGRN_SK.xaml", UriKind.Relative));
    }
}

失效原因

代码核心错误:按钮点击事件中通过new PnlTabMenu_SK()创建的是一个从未被显示过的全新窗口实例,和当前已经打开、承载Page的宿主窗口完全无关,对这个新实例设置隐藏属性自然不会产生任何效果。

修复方法

快速实现:直接获取当前Page所属的宿主窗口

WPF的Page类可以通过Window.GetWindow()方法直接获取承载自身的父窗口实例,不需要手动新建,修改按钮点击逻辑即可:

private void btnAddItems_SK_Click(object sender, RoutedEventArgs e)
{
    // 获取当前Page实际挂载的宿主窗口实例
    PnlTabMenu_SK hostWindow = Window.GetWindow(this) as PnlTabMenu_SK;
    if (hostWindow == null) return;
    
    PnlAddItem_SK pnlAddItem_SK = new PnlAddItem_SK();
    hostWindow.Visibility = Visibility.Hidden;
    // 弹窗关闭后自动恢复宿主窗口显示,不需要可删除
    pnlAddItem_SK.Owner = hostWindow;
    pnlAddItem_SK.ShowDialog();
    hostWindow.Visibility = Visibility.Visible;
}

解耦实现:事件通知(符合MVVM规范)

如果不希望Page直接依赖具体宿主窗口类型,避免耦合,可以通过事件回调让宿主窗口自行处理显示隐藏逻辑:

  1. 在Page类中定义点击事件
    public partial class SubPnlItems_SK : Page
    {
        // 新增按钮点击事件
        public event EventHandler AddItemsRequested;
    
        public SubPnlItems_SK()
        {
            InitializeComponent();
        }
    
        private void btnAddItems_SK_Click(object sender, RoutedEventArgs e)
        {
            // 触发事件,不直接操作窗口
            AddItemsRequested?.Invoke(this, EventArgs.Empty);
        }
        // 其余原有代码不变
    }
    
  2. 修改宿主窗口导航逻辑,订阅Page事件
    // 替换原有直接传Uri的导航方式
    private void NavigateToItemsPage()
    {
        var itemsPage = new SubPnlItems_SK();
        // 订阅Page的按钮点击事件
        itemsPage.AddItemsRequested += (s, args) =>
        {
            this.Visibility = Visibility.Hidden;
            var addWindow = new PnlAddItem_SK();
            addWindow.ShowDialog();
            this.Visibility = Visibility.Visible;
        };
        dockPanel_SK.NavigationService.Navigate(itemsPage);
    }
    

注意:使用该方式时不能直接传Uri导航,需要手动创建Page实例再传入导航方法,否则无法订阅实例事件。

内容的提问来源于stack exchange,提问作者Tharindu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 23:27:29