绑定到 ItemsControl 中的依赖属性
Binding to Dependency Properties within ItemsControl
我有一个带有内联 ItemsSource 的 ItemsControl,如下所示(已简化):
<UserControl>
<ItemsControl>
<ItemsControl.ItemsSource>
<x:Array Type="y:KeyData">
<y:KeyData Name="Name1"/>
<y:KeyData Name="Name2"/>
</x:Array>
</ItemsControl.ItemsSource>
</ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type DateDifferences:KeyData}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</UserControl>
我现在想为每个 KeyData 项绑定另一个值。我试过以下方法:
<UserControl>
<ItemsControl>
<ItemsControl.ItemsSource>
<x:Array Type="y:KeyData">
<y:KeyData Name="Name1" Count="{Binding Count1}"/>
<y:KeyData Name="Name2" Count="{Binding Count2}"/>
</x:Array>
</ItemsControl.ItemsSource>
</ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type DateDifferences:KeyData}">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Count}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</UserControl>
并设置依赖关系 属性 如下:
internal class KeyData : DependencyObject
{
public string Name { get; set; }
public int? Count
{
get { return (int?)GetValue(CountProperty); }
set { SetValue(CountProperty, value); }
}
public static readonly DependencyProperty CountProperty =
DependencyProperty.Register("Count",
typeof(int?),
typeof(KeyData),
new FrameworkPropertyMetadata());
}
并传入数据上下文:
<UserControlName DataContext="{Binding Container.APresenter}"/>
但是,绑定未能找到源...
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or
FrameworkContentElement for target element.
BindingExpression:Path=Removed; DataItem=null;
target element is 'KeyData' (HashCode=4638229);
target property is 'Count' (type 'Nullable`1')
我认为这是依赖关系的意义 属性 - 处理这样的情况?谁能指出我误解的部分?
绑定不知道谁拥有 Count1
和Count2
。可能提供一个 ElementName
来引用所讨论的对象。然后 可能 处理它的 DataContext
例如这个绑定:
="{Binding ElementName=PathBox, Path=DataContext.Count1}"
我发现命名 Xaml 元素(甚至是页面),然后将该命名对象指向其内部,或者如果它是通过其数据上下文的控件,则可以解决大多数绑定问题。
更新
有时必须 x:reference 才能访问命名项。在那种情况下,根据对象使用 x:name 命名它然后访问它。
="{Binding Source={x:Reference PathBox} , Path=Count1}">
所以,最终的解决方案。
忽略显而易见的事实,我最初错过了数据上下文,在那之后,挑战似乎在于让数组中的项目知道外部 ItemsControl 的数据上下文。
我尝试通过 ElementName
和 RelativeSource
进行引用 - 两者似乎都找不到。我试图在 UserControl 上放置一个 x:Name
,并且还按照 OmegaMan 在他的回答中建议的那样使用 x:Reference
进行引用。
其中 None 达到了预期的效果——我能找到的唯一可行的解决方案是使用 "Pipe Object",详见本答案的后半部分。
此后我将数组项重构为单独的用户控件,从而简化了绑定。
我有一个带有内联 ItemsSource 的 ItemsControl,如下所示(已简化):
<UserControl>
<ItemsControl>
<ItemsControl.ItemsSource>
<x:Array Type="y:KeyData">
<y:KeyData Name="Name1"/>
<y:KeyData Name="Name2"/>
</x:Array>
</ItemsControl.ItemsSource>
</ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type DateDifferences:KeyData}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</UserControl>
我现在想为每个 KeyData 项绑定另一个值。我试过以下方法:
<UserControl>
<ItemsControl>
<ItemsControl.ItemsSource>
<x:Array Type="y:KeyData">
<y:KeyData Name="Name1" Count="{Binding Count1}"/>
<y:KeyData Name="Name2" Count="{Binding Count2}"/>
</x:Array>
</ItemsControl.ItemsSource>
</ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type DateDifferences:KeyData}">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Count}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</UserControl>
并设置依赖关系 属性 如下:
internal class KeyData : DependencyObject
{
public string Name { get; set; }
public int? Count
{
get { return (int?)GetValue(CountProperty); }
set { SetValue(CountProperty, value); }
}
public static readonly DependencyProperty CountProperty =
DependencyProperty.Register("Count",
typeof(int?),
typeof(KeyData),
new FrameworkPropertyMetadata());
}
并传入数据上下文:
<UserControlName DataContext="{Binding Container.APresenter}"/>
但是,绑定未能找到源...
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Removed; DataItem=null; target element is 'KeyData' (HashCode=4638229); target property is 'Count' (type 'Nullable`1')
我认为这是依赖关系的意义 属性 - 处理这样的情况?谁能指出我误解的部分?
绑定不知道谁拥有 Count1
和Count2
。可能提供一个 ElementName
来引用所讨论的对象。然后 可能 处理它的 DataContext
例如这个绑定:
="{Binding ElementName=PathBox, Path=DataContext.Count1}"
我发现命名 Xaml 元素(甚至是页面),然后将该命名对象指向其内部,或者如果它是通过其数据上下文的控件,则可以解决大多数绑定问题。
更新
有时必须 x:reference 才能访问命名项。在那种情况下,根据对象使用 x:name 命名它然后访问它。
="{Binding Source={x:Reference PathBox} , Path=Count1}">
所以,最终的解决方案。
忽略显而易见的事实,我最初错过了数据上下文,在那之后,挑战似乎在于让数组中的项目知道外部 ItemsControl 的数据上下文。
我尝试通过 ElementName
和 RelativeSource
进行引用 - 两者似乎都找不到。我试图在 UserControl 上放置一个 x:Name
,并且还按照 OmegaMan 在他的回答中建议的那样使用 x:Reference
进行引用。
None 达到了预期的效果——我能找到的唯一可行的解决方案是使用 "Pipe Object",详见本答案的后半部分。
此后我将数组项重构为单独的用户控件,从而简化了绑定。