Notify Binding for Static Properties in Static Classes

Notify binding for static properties in static classes

Similar to an implementation of INotifyPropertyChanged, static property change notification only works if you use the correct property name when firing the StaticPropertyChanged event.

Use the property name, not the name of the backing field:

public static string ErrorMessgae
{
get { return errorMessage; }
set
{
errorMessage = value;
NotifyStaticPropertyChanged("ErrorMessgae"); // not "errorMessage"
}
}

You should certainly also fix the misspelled property name:

public static string ErrorMessage
{
get { return errorMessage; }
set
{
errorMessage = value;
NotifyStaticPropertyChanged("ErrorMessage");
}
}

The binding should look like this:

Text="{Binding Path=(error:InteractionData.ErrorMessage)}"

See this blog post for details about static property change notification.


You may also avoid to write property names at all by using the CallerMemberNameAttribute:

using System.Runtime.CompilerServices;
...

public static event PropertyChangedEventHandler StaticPropertyChanged;

private static void NotifyStaticPropertyChanged(
[CallerMemberName] string propertyName = null)
{
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(propertyName));
}

You could now call the method without explicitly specifying the property name:

NotifyStaticPropertyChanged();

How can I bind property in a static class?

The Source expression must be Source={x:Static local:Global.Theme} - with braces:

<Border Background="{Binding Source={x:Static local:Global.Theme},
Path=PrimaryBackground}">

Since WPF 4.5 you can also bind directly to static properties.

Turn Theme into a property

public class Global
{
public static Themes.ThemeBase Theme { get; set; } = new NormalWhite();
}

and bind to it with a path expression in parentheses:

<Border Background="{Binding Path=(local:Global.Theme.PrimaryBackground)}">

In case you want to change the Theme value at runtime, you must also implement a change notification, as e.g. shown here: https://stackoverflow.com/a/41823852/1136211

Static property using INotifyPropertyChanged. C#

Just pass null instead of this:

public static event PropertyChangedEventHandler StaticPropertyChanged;

private static void NotifyStaticPropertyChanged([CallerMemberName] string name = null)
{
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(name));
}

See this blog post for details about static property change notification.

Wpf Two-way data binding doesn't work with static classes

  1. WPF data binding works on public properties only, your ipAddressServer is a static field (aka class variable) and not a property, so it won't be used. It's also failing at following proper naming conventions.

  2. Your mess of a binding is the old style static binding, use {Binding Path=(w:Communication.IpAddressServer)} instead (after you fix #1, of course). w is the relevant XAML namespace definition.

  3. Static properties don't have standard notifications for change, since static classes can't implement interfaces (for what I hope are obvious reasons). Instead WPF uses a convention-based approach of using a public static event PropertyChangedEventHandler StaticPropertyChanged and call that to notify changes. It's not clear if you want your property to be mutable, but you mentioned the change notification mechanism explicitly, so just throwing it out there.

Binding to static property

If the binding needs to be two-way, you must supply a path.

There's a trick to do two-way binding on a static property, provided the class is not static : declare a dummy instance of the class in the resources, and use it as the source of the binding.

<Window.Resources>
<local:VersionManager x:Key="versionManager"/>
</Window.Resources>
...

<TextBox Text="{Binding Source={StaticResource versionManager}, Path=FilterString}"/>

INotifyPropertyChanged for static variable

INotifyPropertyChanged works on instance properties. One solution is to use a singleton pattern and keep INotifyPropertyChanged, the other is to use your own event to notify listeners.

Singleton example

public sealed class MyClass: INotifyPropertyChanged
{
private static readonly MyClass instance = new MyClass();
private MyClass() {}

public static MyClass Instance
{
get
{
return instance;
}
}

// notifying property
private string privMyProp;
public string MyProp
{
get { return this.privMyProp; }

set
{
if (value != this.privMyProp)
{
this.privMyProp = value;
NotifyPropertyChanged("MyProp");
}
}
}

// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;

private void NotifyPropertyChanged(String info)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(info));
}
}
}

EDIT: In WPF 4.5, they introduced property changed mechanic for static properties:

You can use static properties as the source of a data binding. The
data binding engine recognizes when the property's value changes if a
static event is raised. For example, if the class SomeClass defines a
static property called MyProperty, SomeClass can define a static event
that is raised when the value of MyProperty changes. The static event
can use either of the following signatures.

public static event EventHandler MyPropertyChanged;
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;

Why I can't bind static property with notification in .net core?

Your binding syntax is wrong. If you use the correct syntax, shown in the article you are referencing, it works fine:

<TextBlock Text="{Binding Path=(local:MainWindow.ResultText)}"/>


Related Topics



Leave a reply



Submit