Home > database >  Can I use XAML to create a binding between two DependencyProperties on the parent Page?
Can I use XAML to create a binding between two DependencyProperties on the parent Page?

Time:09-08

I have a Page called HomePage in a WinUI 3 Desktop App. HomePage has two DependencyProperties, P1 and P2. I would like to create a binding that uses P1 as the source and P2 as the target (assume P1 and P2 are of the same type). This can be done easily in code but, can I create the binding in XAML?

This is the code for the binding:

public sealed partial class HomePage : Page
{
    public HomePage()
    {
        InitializeComponent();

        // Dependency property identifiers are static public fields. This is the identifier of the Target.
        var targetInfo = typeof(HomePage).GetField("P2Property", BindingFlags.Static | BindingFlags.Public);

        if (targetInfo is not null && targetInfo.FieldType == typeof(DependencyProperty))
        {
            Binding bBinding = new() { Path = new PropertyPath("P1"), Source=this, Mode = BindingMode.OneWay };

            // this is a static field (there are no instance versions) and the value is the identifier of the DependencyProperty
            var dp = (DependencyProperty)targetInfo.GetValue(null);

            ClearValue(dp);
            SetBinding(dp, bBinding);       // create the binding
        }
    }

    // P1
    public static readonly DependencyProperty P1Property = DependencyProperty.Register(
        "P1", typeof(object), typeof(HomePage), new PropertyMetadata(null));
    public object P1
    {
        get => (object)GetValue(P1Property);
        set => SetValue(P1Property, value);
    }

    // P2
    public static readonly DependencyProperty P2Property = DependencyProperty.Register(
        "P2", typeof(object), typeof(HomePage), new PropertyMetadata(null));
    public object P2
    {
        get => (object)GetValue(P2Property);
        set => SetValue(P2Property, value);
    }
}

Can the binding (bBinding) be created in XAML instead?

CodePudding user response:

You can do it this way.

<local:HomePage P2="{Binding RelativeSource={RelativeSource Mode=Self}, Path=P1}"/>

CodePudding user response:

This kind of binding is so-called self binding, which is used for binding to/between tag's own properties.

1 - Self-binding

Use RelativeSourceMode.Self to access tag's properties by specifying them in the Pathproperty

<local:HomePage P2="{Binding RelativeSource={RelativeSource Self}, Path=P1}"/>

Almost similar to Andrew's answer (explicit mode specification):

<local:HomePage P2="{Binding RelativeSource={RelativeSource Mode=Self}, Path=P1}"/>

2 - ElementName

You can also try binding through ElementName if your layout contains multiple number of elements of the same type (or self):

<local:HomePage x:Name="MyHomePage" P2="{Binding ElementName=MyHomePage, Path=P1}"/>

More

Explore more about RelativeSource and Binding markup extension to dive deep into it, coz it is really handy thing to use in your further projects. Btw have a look at @james.lee detailed answer on this topic.

  • Related