0

I am making a WPF program by .net5 .

Here is my code:

public class ThemeBase:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        void OnPropertyChanged(string name)=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));


        SolidColorBrush _PrimaryBackground;
        public SolidColorBrush PrimaryBackground
        {
            get => _PrimaryBackground;
            set { _PrimaryBackground = value;OnPropertyChanged("PrimaryBackground"); }
        }
Boolean _IsBlur;
        public Boolean IsBlur
        {
            get => _IsBlur;
            set {
                //some logic
            }
        }
}

And here is a subclass that inherits from it.

public class NormalWhite:ThemeBase
    {
        public NormalWhite() {
            PrimaryBackground = new SolidColorBrush(Colors.Red);
            IsBlur=false;
        }
    }

Finally, I set a static variable in a class named Global.cs:

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

Here is the code in XAML:

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

After the program ran, the Binding Failure reports this error:

Severity    Count   Data Context    Binding Path    Target  Target Type Description File    Line    Project
Error   1   String  PrimaryBackground   Border.Background   Brush   PrimaryBackground property not found on object of type String.  \MainPage.xaml  23  Sample

Why I can't bind it? Thank you.

Melon NG
  • 2,568
  • 6
  • 27
  • 52

1 Answers1

2

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

Clemens
  • 123,504
  • 12
  • 155
  • 268
  • I am afraid VS reports this error:XamlParseException:Type reference cannot find type named“{clr-namespace:Sample;assembly=Sample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null}Global.Theme”. after I Turn Theme into property. – Melon NG Nov 22 '20 at 08:45
  • However, the {Binding Source={x:Static local:Global.Theme}, Path=PrimaryBackground} way work well. – Melon NG Nov 22 '20 at 08:46
  • I can't tell what exactly goes wrong on your side, but when you are using WPF 4.5 or later, the static property Path does of course work. And you will need it in case you change the Theme. Do not forget to write the parentheses around the path expression. – Clemens Nov 22 '20 at 08:52