【问题标题】:WPF Databinding only works with explicit ElementName attributeWPF 数据绑定仅适用于显式 ElementName 属性
【发布时间】:2014-04-24 14:56:23
【问题描述】:

我创建了我的第一个自定义控件,其中包含两个依赖属性。一个是decimal,另一个是我自己的CustomType。所以为了测试它,我创建了一个只有一个窗口的小项目,并尝试通过使用 Window 本身作为数据上下文来绑定它,如下所示:

<somethin:mycontrol MyDependencyProperty="{Binding MyCustomType}"/>

MyCustomType 是 MainWindow.cs 中的一个属性,这不起作用。所以我做了一个猜测,给 MainWindow 起了一个名字,然后指定了 Element 的名字,它的工作原理是这样的:

<Window x:Class="BC.WPF.TestArea.MainWindow" ... x:Name="MyWindow">
...
      <somethin:mycontrol MyDependencyProperty="{Binding ElementName=MyWindow, Path=MyCustomType}"/>

....
</Window>

所以根据我的经验,ElementName 部分不应该是必需的,但它可以工作,所以我很满意,直到我尝试在 ItemsControl 中使用它。然后事情变得非常奇怪。首先我尝试了这个:

<ItemsControl ItemsSource="{Binding ElementName=MyWindow, Path=ObservableMyCustomTypes }">
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="somehting:CustomType" >
            <StackPanel Orientation="Horizontal" >
                <Label Content="{Binding Name }"/>
                <somethin:mycontrol  MyDependencyProperty="{Binding}" />
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

这里奇怪的是CustomType 有一个Name 属性,并且标签中的绑定到Content 有效,但MyDependencyProperty="{Binding}" 无效。我也尝试了MyDependencyProperty="{Binding .}",但没有成功,所以出于好奇,我尝试将Tuple&lt;CustomType&gt; 类型的元素放入集合中,然后像这样绑定到Item1

<ItemsControl ItemsSource="{Binding ElementName=MyWindow, Path=ObservableMyCustomTypes }">
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="system:Tuple" >
            <StackPanel Orientation="Horizontal" >
                <Label Content="{Binding Item1.Name }"/>
                <somethin:mycontrol  MyDependencyProperty="{Binding Item1}" />
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

令人难以置信的是标签中的绑定到Item1.Name 有效,但另一个绑定并没有让我感到困惑,因为现在我真的不知道路径有什么问题,但带有 @ 的那个987654337@ 按预期工作。

发生了什么事?

Here is a link to a zip with the complete test project 如果你好奇的话。

【问题讨论】:

    标签: c# wpf xaml data-binding dependency-properties


    【解决方案1】:

    首先,通过在PercentageOrFixControl 的构造函数中设置DataContext = this; 来打破控件中的DataContext 继承,因此表达式

    PercentageOrFixed="{Binding }"
    

    正在返回控件本身,而不是集合中的 PercentageOrFixed 项。标签的数据上下文是集合的项目,这就是它找到Name 属性的原因。

    从构造函数中删除数据上下文的设置器后,控件中的内部绑定会中断,因为它们会在控件上查找属性。添加

    , RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}
    

    到所有绑定的末尾。例如,第一个 RadioButtonIsChecked 属性应如下所示:

    IsChecked="{Binding UseFix, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
    

    编辑

    为了测试,我删除了Tuple 的使用,因为它不需要,所以集合定义为ObservableCollection&lt;PercentageOrFixed&gt;

    【讨论】:

    • 谢谢,我刚刚看到应用程序的控制台输出,这给了我一个提示:System.Windows.Data 错误:40:BindingExpression 路径错误:在 'object' 上找不到 'Item1' 属性'PercentageOrFixControl'(名称='')'。绑定表达式:路径=项目 1; DataItem='PercentageOrFixControl' (Name='');目标元素是'PercentageOrFixControl'(名称='');目标属性是“PercentageOrFixed”(输入“PercentageOrFixed”)但是你的回答让它更清楚了。非常感谢。
    • 与其完全删除 DataContext = this,不如将其更改为按名称设置根面板的 DataContext 以获得外部绑定,而不需要将 RelativeSource 添加到内部的所有内容中。跨度>
    猜你喜欢
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 2018-03-24
    • 2015-08-09
    • 1970-01-01
    • 2016-06-06
    • 2020-01-02
    • 1970-01-01
    相关资源
    最近更新 更多