简体   繁体   English

在自定义控件中绑定数据

[英]Binding data in custom control

I have a custom control myCustomControl.Xaml我有一个自定义控件myCustomControl.Xaml

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

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

And a cs file myCustomControl.xaml.cs还有一个cs文件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然后我有mainPage.xaml我设置customId

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

I dont understand why is my customId not send from mainPage.xaml to myCustromControl.xaml ?我不明白为什么我的customId没有从mainPage.xaml发送到myCustromControl.xaml What I am doing wrong?我做错了什么? ( ComboBox has no id) ComboBox没有 id)

Binding Does Not Work绑定不起作用

A dependency property is defined on the control itself .依赖属性是在控件本身上定义的 A regular binding without an explicit source uses the current DataContext .没有显式源的常规绑定使用当前DataContext In order to make your binding work, you would have to set the DataContext to the control itself.为了使您的绑定工作,您必须将DataContext设置为控件本身。 Although you can do this in the constructor using DataContext=this;尽管您可以在构造函数中使用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.您可以通过将x:Name分配给您的控件然后使用ElementName来引用它来做到这一点。

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

Alternatively, you can specify a RelativeSource with the custom control type.或者,您可以指定具有自定义控件类型的RelativeSource

<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> .依赖属性必须符合模式<Name>Property并且其包装器属性必须命名为<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) .这里是typeof(myClass) ,但必须是typeof(myCustomControl)

In summary, the dependecy property should be declared like this:总之,dependecy 属性应该这样声明:

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.在 C# 中,您应该遵守类(以及控件)和属性的 Pascal-Casing。 Pascal-cased identifiers start with a capital letter, eg MyCustomControl , CustomIdProperty and CustomId . Pascal 大小写标识符以大写字母开头,例如MyCustomControlCustomIdPropertyCustomId

Replace nameof(customIdProperty) with nameof(customId) , and typeof(myClass) with typeof(myCustomControl)nameof(customIdProperty)替换为nameof(customId) ,并将typeof(myClass)替换为typeof(myCustomControl)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM