1

For the past couple of days I have been tinkering trying to find a solution for the given situation below.

I have a base class AppColors containing different color properties:

public class AppColors
{
    public static Brush ColorTransparent    { get; private set; }
    public static Brush ColorBlack          { get; private set; }
        
    public AppColors()
    {
        ColorTransparent = new SolidColorBrush(U.Hex2Color("#00ffffff"));
        ColorBlack       = new SolidColorBrush(U.Hex2Color("#ff000000"));
    }
}   

My ColorPage ViewModel uses the AppColors class as its base:

public class ColorPageViewModel: AppColors
{
    public static Brush ColorCustom   { get; private set; }

    public ColorPageViewModel ()
    {
        ColorCustom = new SolidColorBrush(U.Hex2Color("#ffff1234"));
    }
}

Inside the ColorPage XAML I want to make a binding to the ColorBlack property from the base color class.

<Page
    x:Class="MyApp.Pages.ColorPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="using:MyApp"
    xmlns:vm="using:MyApp.ViewModels"
    mc:Ignorable="d">

    <Page.DataContext>
        <vm:ColorPageViewModel />
    </Page.DataContext>

    <!-- the property ColorBlack can not be retrieved, but no error is given -->
    <Grid Background="{Binding ColorBlack}"></Grid>
</Page>

The binding to the ColorBlack property is not used when I run the application. I was expecting it to be retrieved from the base color class.

I can fix the problem by declaring a page resource and use that as my source for the binding, but that defeats the whole purpose of using the color class as a base.

<Page.Resources>
    <local:AppColors x:Key="AppColors" />
</Page.Resources>

<Page.DataContext>
    <vm:ColorPageViewModel />
</Page.DataContext>

<!-- the property ColorBlack works now! -->
<Grid Background="{Binding ColorBlack, Source={StaticResource AppColors}}"></Grid>

Any advice on how to access the properties from the base color class?

Richard Avalos
  • 555
  • 5
  • 18
  • 2
    I never bound to a static member, are you positive the error isn't related to this, instead of the base class? Does the binding work as expected when you use `ColorCustom`? Everytime I had a need for binding to static I use `{x:Static xxx}` – Rand Random Aug 12 '22 at 11:33
  • @RandRandom yes, ColorCustom does indeed work. – Richard Avalos Aug 12 '22 at 11:34
  • You're not calling the constructor of the base class in ColorPageViewModel – Paolo Iommarini Aug 12 '22 at 11:35
  • 1
    @PaoloIommarini - doesn't matter empty base ctor will be called automatically | https://stackoverflow.com/questions/13166019/will-the-base-class-constructor-be-automatically-called – Rand Random Aug 12 '22 at 11:37
  • went ahead and tested it, first in wpf since I am more familar with it and there it works as intended, but yeah uwp doesn't produce the intended result – Rand Random Aug 12 '22 at 11:48
  • Output gives this error: `Error: BindingExpression path error: 'ColorBlack' property not found on 'App8.ColorPageViewModel'. BindingExpression: Path='ColorBlack' DataItem='App8.ColorPageViewModel'; target element is 'Windows.UI.Xaml.Controls.Grid' (Name='null'); target property is 'Background' (type 'Brush')` – Rand Random Aug 12 '22 at 11:50
  • and yes, a non static property also works as intended - so only static property on base class fails – Rand Random Aug 12 '22 at 11:53
  • 1
    would using a singleton, be an alternative to the static properties? - https://stackoverflow.com/questions/2155688/what-is-a-singleton-in-c – Rand Random Aug 12 '22 at 11:59
  • @RandRandom I just tested this and this is a valid alternative, but would require a rewrite of the class and its usage across the app. Ill keep the question open for now to see what other options people come up with. Thank you so far. – Richard Avalos Aug 12 '22 at 12:54

1 Answers1

0

Any advice on how to access the properties from the base color class?

ColorBlack is not an instance/local property of the view model.

Use {x:Bind} when you bind to static properties:

<Grid Background="{x:Bind vm:ColorPageViewModel.ColorBlack}"></Grid>
Nkosi
  • 235,767
  • 35
  • 427
  • 472
mm8
  • 163,881
  • 10
  • 57
  • 88
  • Any idea why it work with WPF if as you say "is not a property of the view model.", why would evaluating the binding expression be different from wpf? – Rand Random Aug 15 '22 at 15:36
  • WPF is certainly different from UWP. What's your point/question? There is difference between binding to a instance property and a static property in WPF as well. – mm8 Aug 16 '22 at 10:23
  • My points, are 1) answer ignores the fact that the static member `ColorCustom` of the derived class is working as intended 2) first revision could be understood as only directly declared members of the view model can be accessed, not a member of the bas class 3) second revision could be understood as only instance property work, see point 1 in that regard 4) UWP and WPF share ALOT and one could assume that the binding evaluation would be identical, why the change? why was it necessary for UWP to drop support for static members of a bas class? – Rand Random Aug 16 '22 at 10:45
  • UWP and WPF don't share the same XAML stack. And the actual question of "any advice on how to access the properties from the base color class" has apparently been answered. – mm8 Aug 16 '22 at 10:48