简体   繁体   中英

Update XAML TextBlock with value of public property from other class

I have in my C# WPF solution as follows: Mainwindow with a startupControl (always running) Dialogwindow with diffent other controls. A public Helper-class containing some public static properties to indicate what department at customer is active, and for who i have focus on at the moment.

I want simply two XAML textBlocks displayed in my Startupcontrol to show the property names if and when the value for a department or costumer has been set.

I think it could properbly work smooth with some sort of binding, but i dont know anything about bindings, other than they exists.

Is it possible in any way from my controls in my dialogwindow, to change the value of the 2 textblocks in the Startupcontrol ?

As the program is small and I know exactly when the values change, I think i could make a function setting the value ex.:

activeDepartmentTextBlock.Text = HelperClass.ActiveDepartment.Name;

But from my control.cs in the DialogWindow, it seems to be possible to reach the activeDepartmentTextBlock.

Anyone who can help me ?

Since WPF 4.5, binding to static properties with property change notification is quite simple.

The example below assumes that you want to notify about the change of the ActiveDepartment property of the HelperClass (and not about the Name property of the Department object). In addition to the static property, declare a static event named StaticPropertyChanged and fire it when the static property changes:

public class Department
{
    public string Name { get; set; }
}

public class HelperClass
{
    public static event PropertyChangedEventHandler StaticPropertyChanged;

    private static Department activeDepartment;

    public static Department ActiveDepartment
    {
        get => activeDepartment;
        set
        {
            activeDepartment = value;
            StaticPropertyChanged?.Invoke(null,
                new PropertyChangedEventArgs(nameof(ActiveDepartment)));
        }
    }
}

You can bind to a static property like this:

<TextBlock Text="{Binding Path=(local:HelperClass.ActiveDepartment).Name}"/>

Binding is a good solution but you have static property so you can't use binding infrastructure directly to get notified of updates since there's no DependencyObject (or object instance that implement INotifyPropertyChanged ) involved.

If the value does change and you need to update TextBlock 's value in main window yo can create a singleton instead of static class to contain the value and bind to that.

An example of the singleton:

public class HelperClass : DependencyObject {
    public static readonly DependencyProperty ActiveDepartmentProperty =
        DependencyProperty.Register( "ActiveDepartment", typeof( Department ),
        typeof( HelperClass ), new UIPropertyMetadata( "" ) );
    public Department ActiveDepartment {
        get { return (Department) GetValue( ActiveDepartmentProperty ); }
        set { SetValue( ActiveDepartmentProperty, value ); }
    }

    public static HelperClass Instance { get; private set; }

    static HelperClass() {
        Instance = new HelperClass();
    }
}

So binding will work like in an example below:

<TextBox Text="{Binding Source={x:Static local:HelperClass.Instance}, Path=ActiveDepartment.Name}"/>

It might look like a hard way and that's it. You can use events model instead and add the event to your HelperClass . MainWindow can add event handler and change activeDepartmentTextBlock value when event raised.

public MainWindow()
{
    InitializeComponent();
    HelperClass.Instance.DepartmentChanged += OnDepartmentChanged;
}

private void OnDepartmentChanged(Department newDepartment)
{
    activeDepartmentTextBlock.Text = newDepartment.Name;
}

Update . If you want to have the simplest solution you can break encapsulation principle and pass MainWindow as a parameter to DialogWindow and make activeDepartmentTextBlock public. So you will be able to save the link to the MainWindow in the DialogWindow 's field and just change the text when you need in DialogWindow :

this.mainWindow.activeDepartmentTextBlock.Text = HelperClass.ActiveDepartment.Name;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM