C# WPF:关闭 Window之后,无法设置 Visibility,也无法调用 Show、ShowDialogor等等;或者一次事件打开多个同样的窗口

前情提要:最近公司同事在做WPF的多个客户端的项目,客户端之间的通信是通过服务器转发实现的。

出现的问题:1.客户端A点击按钮a,A显示界面P正常,客户端B显示界面P正常;但是界面P跳转到界面P1后会出现很多界面;

                      2.修改之后,又报错:关闭 Window之后,无法设置 Visibility,也无法调用 Show、ShowDialogor等等;

当时看了代码第一反应是实例有问题,close()方法不会销毁你的实例,导致每次点击都会增加一个实例。看到这里自然而然就想到了单例模式。虽然简单,但是实用啊,哈哈哈!

但是我是第一次接触C#,很多东西也不是很清楚,有不对的,欢迎大家指正;

1.界面P、P1都需要写一个单例的接口:

//P
        static P p_instance = null;
        static public P instance()
        {
            if (p_instance == null)
                p_instance = new P();
            return p_instance;
        }
//P1
        static P1 p1_instance = null;
        static public P1 instance()
        {
            if (p1_instance == null)
                p1_instance = new P1();
            return p1_instance;
        }

2.界面P中的事件:

public void ToP1()
        {
            Dispatcher.BeginInvoke(new Action(delegate 
            {
                this.Close(); //关闭界面P
                if(p_instance != null)
                    p_instance.Close(); //关闭多余的P
                p_instance = null; //销毁P,保证下次打开是一个新的P
                
                P1.instance().Show(); //打开界面P1
            }));
        }

3.界面P1中的事件:

public void ToP()
        {
            Dispatcher.BeginInvoke(new Action(delegate 
            {
                this.Close(); //关闭界面P1
                if(p1_instance != null)
                    p1_instance.Close();
                p1_instance = null;
                
                P.instance().Show(); //打开界面P
            }));
        }

客户端A和客户端B的代码是完全一样的,这样操作就好了,没有多余的界面,也不会报错。

如果哪里写的有问题,欢迎大家指出来!

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPF 中,一个窗口Window)通常对应一个 UI 线程,而 UI 线程是用来处理用户界面交互的。当你打开第二个窗口时,它也会在同一个 UI 线程上运行。在 WPF 中,UI 元素通常只能由创建它的线程访问和修改。 如果第二个窗口无法改变第一个窗口中的控件,但可以调用相关属性,可能是因为你在第二个窗口的代码中尝试修改了第一个窗口的控件。这样的操作违反了 WPF 的线程模型。 解决这个问题的一种方法是使用线程间通信机制,例如使用 `Dispatcher` 对象。你可以将需要修改的操作包装在一个 `Action` 中,并通过 `Dispatcher` 对象将其发送到第一个窗口的 UI 线程上执行,以避免线程间的冲突。 以下是一个示例代码片段,演示了如何在第二个窗口调用第一个窗口的控件属性: ```csharp // 第一个窗口代码 public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } public string TextBlockText { get { return textBlock.Text; } set { textBlock.Text = value; } } } // 第二个窗口代码 public partial class SecondWindow : Window { private MainWindow mainWindow; public SecondWindow(MainWindow mainWindow) { InitializeComponent(); this.mainWindow = mainWindow; } private void ChangeTextButton_Click(object sender, RoutedEventArgs e) { mainWindow.Dispatcher.Invoke(() => { mainWindow.TextBlockText = "New text from second window"; }); } } ``` 在这个示例中,`MainWindow` 类代表第一个窗口,`SecondWindow` 类代表第二个窗口。在 `SecondWindow` 中,我们将 `MainWindow` 的实例传递给构造函数,并通过 `mainWindow.TextBlockText` 属性来修改第一个窗口中的文本块。 希望这个解释能帮到你!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值