1

How can I use an ObservableObject (from Community Toolkit) as a Binding Target in code and XAML in a WinUI 3 Desktop app?

Here's a simple (partial) homepage example:

<!-- Home.xaml -->
<Page
    x:Class="PFSI.Views.Home"
    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:vms="using:PFSI.ViewModels"
    mc:Ignorable="d" >
    
    <Page.DataContext>
        <vms:HomeViewModel x:Name="ViewModel" />
    </Page.DataContext>
    
    <Grid x:Name="ContentArea" >
        <TextBlock x:Name="TBox" Text="This text should be shaded." Foreground="{Binding Shade}" />
    </Grid>
</Page>
// Home.xaml.cs
public partial class HomePage : Page
{
    public HomePage()
    {
        InitializeComponent();
    }
}
// HomeViewModel.cs
public class HomeViewModel : ObservableObject
{
    public HomeViewModel()
    {
        Classes.TraceListener.TraceMessage(GetType().Name);
    }

    [ObservableProperty]
    private SolidColorBrush shade;
}

Using the property Shade as a source is straightforward in XAML (see the TextBlock in Home.xaml) or in code:

Binding bBinding = new() { Path = new PropertyPath("Shade"), Source = ViewModel, Mode = BindingMode.OneWay };
TBox.SetBinding(TextBox.ForegroundProperty, bBinding);

But what if I want to make the property Shade the target of the binding (that is, I want to set Shade with the binding)?

BindingOperations.SetBinding(DependencyObject target, DependencyProperty dp, BindingBase binding) requires a DependencyObject (which HomeViewModel is not, it's an ObservableObject) and a DependencyProperty identifier (which Shade doesn't have as it's a normal property).

I'm sure this is possible but I'm at a loss for the moment. Any help most welcome.

aturnbul
  • 347
  • 2
  • 12
  • You seem to be looking for ``TwoWay`` binding. For example, a color picker control? – Andrew KeepCoding Sep 06 '22 at 14:28
  • No, not at all, although I thought of that as a way to deal with this. I have an independent process that periodically produces a statistic. I'd like that statistic to set an ObservableProperty (the Target). The ObservableProperty may well be bound as a Source for other items in the model. The color was just an easy example. Thanks very much, though. – aturnbul Sep 06 '22 at 14:34
  • A target property of a binding must be a dependency property of a dependency object. – mm8 Sep 06 '22 at 14:36

1 Answers1

1

How can I use an ObservableObject (from Community Toolkit) as a Binding Target in code and XAML in a WinUI 3 Desktop app?

You can't since the target property of a binding must be a dependency property.

I'm sure this is possible ...

Not without turning the target property into a dependency property (and the class into a DependencyObject).

I don't see why you would need to extend both ObservableObject and DependencyObject though. It's one or the other, i.e. either your class is some kind of view model or some kind of control.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • Thank you. I know I couldn't find a way to target anything but a DependencyProperty with a binding (I also couldn't find anything that explicitly required one in a binding), but I wonder why? Wouldn't anything that notifies satisfy the binding requirements? As for my case, it's a ViewModel that I'd like to set in code. – aturnbul Sep 06 '22 at 14:53
  • Why? To enable the property to be tracked and influenced by the dedicated property system which for example includes just-in-time property determination mechanisms such as data binding, animations and storyboards. – mm8 Sep 06 '22 at 15:02