将 Collection 类型的 AttachedProperty 绑定到 TemplatedParent
Binding AttachedProperty of Collection type to TemplatedParent
我想创建一个附加的 属性 来保存 MenuItem 对象的集合。这些将在我的 GroupBox 自定义 ControlTemplate 中使用。在那个 ControlTemplate 中,我想使用我的自定义 DropDownButton,它继承自 ItemsControl,并将 MenuItems 放在它的 Popup 中。
我在这个网站上找到了小费:
https://siderite.dev/blog/collection-attached-properties-with.html
这是我拥有的:
附加属性:
public class General {
public static readonly DependencyProperty MenuItemsProperty =
DependencyProperty.RegisterAttached(
"MenuItemsInternal",from convention
typeof(ObservableCollection<MenuItem>),
typeof(General),
new PropertyMetadata(default(ObservableCollection<MenuItem>)));
public static ObservableCollection<MenuItem> GetMenuItems(UIElement element)
{
var collection = (ObservableCollection<MenuItem>) element.GetValue(MenuItemsProperty);
if (collection == null)
{
collection = new ObservableCollection<MenuItem>();
element.SetValue(MenuItemsProperty, collection);
}
return collection;
}
public static void SetMenuItems(UIElement element, ObservableCollection<MenuItem> value)
{
element?.SetValue(MenuItemsProperty, value);
}
}
附加属性的用法:
...
<GroupBox Style="{StaticResource Style.GroupBox.EditableSubSection}">
<ap:General.MenuItems>
<MenuItem Header="Aktion abc" />
<MenuItem Header="Aktion xyz" />
</ap:General.MenuItems>
</GroupBox>
到目前为止一切顺利。这一切都有效。我的问题是我找不到在 GroupBox 的 ControlTemplate 中使用 MenuItems 集合的方法。
<Style x:Key="Style.GroupBox.EditableSubSection"
TargetType="{x:Type GroupBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupBox}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{TemplateBinding Header}" />
<Separator Grid.Row="1" />
<ContentPresenter Grid.Row="2" />
<Grid Grid.Row="0" HorizontalAlignment="Right">
...
<controls:DropDownButton Width="{Binding ActualHeight,
RelativeSource={RelativeSource Self}}"
ItemsSource="{Binding Path=(ap:General.MenuItems),
RelativeSource={RelativeSource TemplatedParent}}" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
当运行这个问题似乎是绑定
ItemsSource="{Binding Path=(ap:General.MenuItems), RelativeSource={RelativeSource TemplatedParent}}"
我收到异常消息:
InvalidOperationException: Property path is not valid. 'General' does not have a public property named 'MenuItems'
有没有人以前遇到过这种情况或关于如何绑定到具有非常规名称的 AttachedProperty 的任何提示?
@Jinish 在评论中提供了答案。
Your property name as I can see from the code is "MenuItemsInternal". That't the name that will be used for WPF binding purpose as far as I am aware
将绑定更改为以下内容即可解决问题
ItemsSource="{Binding Path=(ap:General.MenuItemsInternal), RelativeSource={RelativeSource TemplatedParent}}"
由于无法将评论转换为答案,我正在回答我自己的问题,引用元上建议的评论:https://meta.stackexchange.com/a/1558
我想创建一个附加的 属性 来保存 MenuItem 对象的集合。这些将在我的 GroupBox 自定义 ControlTemplate 中使用。在那个 ControlTemplate 中,我想使用我的自定义 DropDownButton,它继承自 ItemsControl,并将 MenuItems 放在它的 Popup 中。
我在这个网站上找到了小费:
https://siderite.dev/blog/collection-attached-properties-with.html
这是我拥有的:
附加属性:
public class General {
public static readonly DependencyProperty MenuItemsProperty =
DependencyProperty.RegisterAttached(
"MenuItemsInternal",from convention
typeof(ObservableCollection<MenuItem>),
typeof(General),
new PropertyMetadata(default(ObservableCollection<MenuItem>)));
public static ObservableCollection<MenuItem> GetMenuItems(UIElement element)
{
var collection = (ObservableCollection<MenuItem>) element.GetValue(MenuItemsProperty);
if (collection == null)
{
collection = new ObservableCollection<MenuItem>();
element.SetValue(MenuItemsProperty, collection);
}
return collection;
}
public static void SetMenuItems(UIElement element, ObservableCollection<MenuItem> value)
{
element?.SetValue(MenuItemsProperty, value);
}
}
附加属性的用法:
...
<GroupBox Style="{StaticResource Style.GroupBox.EditableSubSection}">
<ap:General.MenuItems>
<MenuItem Header="Aktion abc" />
<MenuItem Header="Aktion xyz" />
</ap:General.MenuItems>
</GroupBox>
到目前为止一切顺利。这一切都有效。我的问题是我找不到在 GroupBox 的 ControlTemplate 中使用 MenuItems 集合的方法。
<Style x:Key="Style.GroupBox.EditableSubSection"
TargetType="{x:Type GroupBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupBox}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{TemplateBinding Header}" />
<Separator Grid.Row="1" />
<ContentPresenter Grid.Row="2" />
<Grid Grid.Row="0" HorizontalAlignment="Right">
...
<controls:DropDownButton Width="{Binding ActualHeight,
RelativeSource={RelativeSource Self}}"
ItemsSource="{Binding Path=(ap:General.MenuItems),
RelativeSource={RelativeSource TemplatedParent}}" />
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
当运行这个问题似乎是绑定
ItemsSource="{Binding Path=(ap:General.MenuItems), RelativeSource={RelativeSource TemplatedParent}}"
我收到异常消息:
InvalidOperationException: Property path is not valid. 'General' does not have a public property named 'MenuItems'
有没有人以前遇到过这种情况或关于如何绑定到具有非常规名称的 AttachedProperty 的任何提示?
@Jinish 在评论中提供了答案。
Your property name as I can see from the code is "MenuItemsInternal". That't the name that will be used for WPF binding purpose as far as I am aware
将绑定更改为以下内容即可解决问题
ItemsSource="{Binding Path=(ap:General.MenuItemsInternal), RelativeSource={RelativeSource TemplatedParent}}"
由于无法将评论转换为答案,我正在回答我自己的问题,引用元上建议的评论:https://meta.stackexchange.com/a/1558