0

I couldn't find a simple solution to this problem. That's why I'm asking.

I have a WPF window like this:

<Window x:Class="WPF_Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Width="640" Height="480">

    <Button Name="xaml_button" Content="A Text."/>
</Window>

And a MainWindow class:

using System.Windows;
using System.Threading;

namespace WPF_Test
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            xaml_button.Content = "Text changed on start.";
        }
    }

    private void xaml_button_Click()
    {
        Threading.t1.Start();
        UIControl.ChangeButtonName("Updated from another CLASS.");
    }
}

The button's Content property successfully changed itself. But what I want to do, is to change the property in another class or thread. What I tried is this:

class UIControl
{
    public static void ChangeButtonName(string text)
    {
        var window = new MainWindow();
        window.xaml_button.Content = text;
    }
}

It obviously doesn't work, because the public MainWindow() changes the Content property back to the original one, and brings some issues along with it.

Also I want to use this while multithreading. My simple threading class looks like this:

class Threading
{
    public static Thread t1 = new Thread(t1_data);

    static void t1_data()
    {
        Thread.Sleep(2000);
        UIControl.ChangeButtonName("Updated from another THREAD.");
    }
}
Jakub Loksa
  • 537
  • 1
  • 14
  • 32
  • Normally you need to dispatch ui changes from another thread to the main Thread. Like there described: http://stackoverflow.com/a/14890338 – Jan Peter Nov 12 '15 at 20:24

1 Answers1

2

To do this, I'd recommend declaring a static variable that holds a UI control of your likings, in this case, a Button. Also add using System.Windows.Controls; at the beginning. So your code should look like this:

using System.Threading;
using System.Windows;
using System.Windows.Controls;

namespace WPF_Test
{
    public partial class MainWindow : Window
    {
        public static Button xamlStaticButton;

        public MainWindow()
        {
            InitializeComponent();
            xamlStaticButton = xaml_button;
            xamlStaticButton.Content = "Text changed on start";
        }

        private void xaml_button_Click(object sender, RoutedEventArgs e)
        {
            Threading.t1.Start();
            UIControl.ChangeButtonName("Updated from another CLASS.");
        }
    }
}

So pretty much what I did was to make a placeholder for the button, then assigning it on start.

class UIControl : MainWindow
{
    public static void ChangeButtonName(string text)
    {
        App.Current.Dispatcher.Invoke(delegate {
            xamlStaticButton.Content = text;
        });
    }
}

Now I inherited the MainWindow class to the UIControl class for the sake of convenience. Also to make this work with multithreading, I added the App.Current.Dispatcher.Invoke(delegate { /*your UI code you want to execute*/});. This will make sure your UI will update even if you are on another thread.

Jakub Loksa
  • 537
  • 1
  • 14
  • 32