Home > Blockchain >  Binding data in custom control
Binding data in custom control

Time:09-06

I have a custom control myCustomControl.Xaml

<UserControl.Resources>
    ...
</UserControl.Resources>

<ComboBox Name="myCustomComboBoxParent"
          someId = "{Binding customId}"
          .../>

And a cs file myCustomControl.xaml.cs

public static readonly DependencyProperty customIdProperty = DependencyProperty.Register(
    nameof(customIdProperty), typeof(string), typeof(myClass),
    new FrameworkPropertyMetadata(
        "", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

public string customId
{
    get { return (string)GetValue(customIdProperty); }
    set { SetValue(customIdProperty, value); }
}

And then I have mainPage.xaml where I set customId

<local:customComboBox x:Name="myCustomComboBoxChild1" customId = "someIdToBeSended" .../>

I dont understand why is my customId not send from mainPage.xaml to myCustromControl.xaml? What I am doing wrong? (ComboBox has no id)

CodePudding user response:

Binding Does Not Work

A dependency property is defined on the control itself. A regular binding without an explicit source uses the current DataContext. In order to make your binding work, you would have to set the DataContext to the control itself. Although you can do this in the constructor using DataContext=this;, you should not do it, otherwise the custom control will not inherit its data context from parents.

What you should do instead is specify the control as source in your binding. You can do this by assigning an x:Name to your control and then using ElementName to refer to it.

<UserControl ...
             x:Name="This">
    <Grid>
       <ComboBox SomeProperty="{Binding customId, ElementName=This}"
                 .../>
   </Grid>
</UserControl>

Alternatively, you can specify a RelativeSource with the custom control type.

<ComboBox SomeProperty="{Binding customId, RelativeSource={RelativeSource AncestorType=local:myCustomControl}}"
          .../>

Dependency Property Definition

Your dependency property definition is wrong.

  • A dependency property must fit the pattern <Name>Property and its wrapper property must be named <Name>. The name of the wrapper property, not the dependency property is passed as first parameter. Although this does not have an effect in your concrete scenario, it will cause issues later.
  • The owner type must be the type of the control where the dependecy property is defined. Here it is typeof(myClass), but must be typeof(myCustomControl).

In summary, the dependecy property should be declared like this:

public static readonly DependencyProperty customIdProperty = DependencyProperty.Register(
   nameof(customId), typeof(string), typeof(myCustomControl),
   new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

Another remark on naming. In C# you should adhere to Pascal-Casing for classes (and therefore controls, too) and properties. Pascal-cased identifiers start with a capital letter, e.g. MyCustomControl, CustomIdProperty and CustomId.

CodePudding user response:

Replace nameof(customIdProperty) with nameof(customId), and typeof(myClass) with typeof(myCustomControl)

  • Related