[英]Custom Control ContextMenu ItemSource doesn't update when bound DependencyProperty is set
I have created a custom control with a style. 我创建了具有样式的自定义控件。 Everything is working fine but the ContextMenu I'm trying to add doesn't show any items.
一切工作正常,但是我要添加的ContextMenu没有显示任何项目。
ButtonAnalysisControl (Custom Control) ButtonAnalysisControl(自定义控件)
internal class ButtonAnalysisControl : Control
{
static ButtonAnalysisControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonAnalysisControl), new FrameworkPropertyMetadata(typeof(ButtonAnalysisControl)));
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public Brush BackgroundBrush
{
get { return (Brush)GetValue(BackgroundBrushProperty); }
set { SetValue(BackgroundBrushProperty, value); }
}
public ObservableCollection<ViewCommand> ChildCommands
{
get { return (ObservableCollection<ViewCommand>)GetValue(ChildCommandsProperty); }
set { SetValue(ChildCommandsProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(ButtonAnalysisControl), new UIPropertyMetadata(string.Empty));
public static readonly DependencyProperty BackgroundBrushProperty =
DependencyProperty.Register("BackgroundBrush", typeof(Brush), typeof(ButtonAnalysisControl), new UIPropertyMetadata(Brushes.Transparent));
public static readonly DependencyProperty ChildCommandsProperty =
DependencyProperty.Register("ChildCommands", typeof(ObservableCollection<ViewCommand>), typeof(ButtonAnalysisControl), new UIPropertyMetadata(null));
}
Generic.xaml (ButtonAnalysisControl style) Generic.xaml(ButtonAnalysisControl样式)
<Style TargetType="anal:ButtonAnalysisControl">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseDown">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="anal:ButtonAnalysisControl">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock TextAlignment="Center"
VerticalAlignment="Stretch"
Foreground="{StaticResource CommandBarForeground}"
Background="{StaticResource MainForegroundBrush}"
FontFamily="{StaticResource FontFamily}"
FontSize="10"
Grid.Column="0"
Grid.Row="0">
<TextBlock.Text>
<Binding Path="Text" StringFormat="{}{0}%" RelativeSource="{RelativeSource TemplatedParent}" />
</TextBlock.Text>
</TextBlock>
<Rectangle Grid.Column="0"
Grid.Row="1">
<Rectangle.Fill>
<Binding Path="BackgroundBrush" RelativeSource="{RelativeSource TemplatedParent}" />
</Rectangle.Fill>
</Rectangle>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<ContextMenu.ItemsSource>
<Binding RelativeSource="{RelativeSource TemplatedParent}" Path="ChildCommands"/>
</ContextMenu.ItemsSource>
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="MenuItem.Header" Value="{Binding Command.Text}"/>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
ButtonAnalysisControls are created at runtime and they are set as the content of an adorner (this happens in the constructor of the adorner). ButtonAnalysisControls在运行时创建,并将它们设置为装饰器的内容(这发生在装饰器的构造函数中)。 Relevant code:
相关代码:
public ButtonAnalysisAdorner(UIElement adornedElement, int numberOfTimesFieldFilled, int numberOfLoggedViews, ObservableCollection<ViewCommand> childCommands)
: base(adornedElement)
{
_visuals = new VisualCollection(this);
_contentPresenter = new ContentPresenter();
ButtonAnalysisControl bac = new ButtonAnalysisControl();
bac.Text = percentage.ToString(CultureInfo.InvariantCulture);
bac.BackgroundBrush = PercentColorRanges.GetColorFromPercentage((int)percentage, 0.75);
bac.ToolTip = ToolTipValue(numberOfTimesFieldFilled, numberOfLoggedViews);
bac.ChildCommands = childCommands;
Content = bac;
_visuals.Add(_contentPresenter);
}
I inspected ButtonAnalysisControl with Snoop. 我用Snoop检查了ButtonAnalysisControl。 ChildCommands doesn't always have items.
ChildCommands并不总是具有项目。 But I looked at a ButtonAnalysisControl from which I know it has ChildCommands.
但是我看了一个ButtonAnalysisControl,从中我知道它具有ChildCommands。 I saw that the ChildCommands dependency property had a collection with two items and ButtonAnalysisControl.ContextMenu.Items had value: 0. I don't know why the contextmenu doesn't have any items, I want the contextmenu to be bound with ChildCommands.
我看到ChildCommands依赖项属性有一个包含两个项目的集合,而ButtonAnalysisControl.ContextMenu.Items的值是:0。我不知道为什么contextmenu没有任何项目,我希望contextmenu与ChildCommands绑定。 How to fix this?
如何解决这个问题?
I don't think the Templated Parent
binding will work like you want it to. 我认为
Templated Parent
绑定不会像您希望的那样工作。 The ContextMenu
definition isn't in a template. 该
ContextMenu
定义不是一个模板。
You could try something like this: 您可以尝试这样的事情:
<Style TargetType="anal:ButtonAnalysisControl">
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="anal:ButtonAnalysisControl">
<Grid Background="Transparent" Tag="{Binding ChildCommands,RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ContextMenu>
<ContextMenu ItemsSource="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
...
A couple of notes here: 这里有几点注意事项:
DataContext
inheritance, that's why we're going through the Tag
property DataContext
继承,这就是为什么我们要通过Tag
属性 MouseDown
trigger as well to be in the template MouseDown
触发器才能进入模板
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.