Change WPF mainwindow label from another class and separate thread

大城市里の小女人 提交于 2019-12-03 03:58:10

I resolved my question, hope somebody will need this. But don't know whether this is the optimized way.

In my mainWindow.xaml.cs :

    public  MainWindow()
    {
      main = this;
    }

    internal static MainWindow main;
    internal string Status
    {
        get { return status_lable.Content.ToString(); }
        set { Dispatcher.Invoke(new Action(() => { status_lable.Content = value; })); }
    }

from my SignIn.cs class

 MainWindow.main.Status = "Irantha has signed in successfully";

This works fine for me. You can find more details from here, Change WPF window label content from another class and separate thread

cheers!!

try below snippet:

status_lable.Dispatcher.Invoke(...)

Thanks to the answers, they led me in the right direction. I ended up with this simple solution:

public partial class MainWindow : Window
{
    public static MainWindow main;

    public MainWindow()
    {
        InitializeComponent();                        
        main = this;
    }
}

Then in my eventhandler in another class that runs in a different thred:

internal static void pipeServer_MessageReceived(object sender, MessageReceivedEventArgs e)
    {
        MainWindow.main.Dispatcher.Invoke(new Action(delegate()
        {
            MainWindow.main.WindowState = WindowState.Normal;
        }));
    }

This to show the minimized window when i message is received via a namedPipeline.

Thank you! I wound up with a slightly different solution, but you definitely pointed me in the right direction with your answer.

For my application, I have a lot of controls in main, and most of the method calls on main were occurring from within the scope of main, so it was simpler to use the default { get; set } within MainWindow.xaml.cs (or to just define the controls in XAML).

In my parent window's code-behind, I launch the MainWindow in a separate thread like this (simplified example). The key is to define main globally, even though it is instantiated inside of Window_Loaded():

    public ParentWindow()
    {
        InitializeComponent();
    }

    MainWindow main;

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        Thread otherThread = new Thread(() =>
        {
            main = new MainWindow();
            main.Show();

            main.Closed += (sender2, e2) =>
                main.Dispatcher.InvokeShutdown();

            System.Windows.Threading.Dispatcher.Run();
        });

        otherThread.SetApartmentState(ApartmentState.STA);
        otherThread.Start();

    }

Then in my MainWindow code-behind, I just interact with the controls as though it is a simple single-threaded application (there is no control of the parent thread from the child thread in my case). I can, however, control main from the parent thread like this:

private void button_Click(object sender, RoutedEventArgs e)
        {
            main.Dispatcher.Invoke(new Action(delegate () 
                {
                    main.myControl.myMethod(); 
                }));

        }

By doing it this way, I avoid the complexity of defining everything in code-behind and using the dispatcher from within the code-behind of MainWindow.xaml.cs. There are only a few spots in my application where I modify main from the parent window, so this was simpler for me, but your approach seems equally valid. Thanks again!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!