Reputation: 303
I have a problem with binding a context menu to textbox's attached property. So I have TextBox and it has a context menu on right click. So how to bind context menu's property to TextBox's attached property in WPF XAML? Here I trying bind to TextBox but it not helps
<Style x:Key="DefaultTextBox" TargetType="{x:Type TextBox}">
<Setter Property="BorderBrush" Value="{DynamicResource ThemeSecondary}"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu x:Name="uiContexMenu">
<ContextMenu.ItemsSource>
<CompositeCollection>
<MenuItem Command="Cut" Header="Cut">
<MenuItem.Icon>
<Viewbox Width="16" Height="16">
<TextBlock FontFamily="{DynamicResource IconFont}" Text=""/>
</Viewbox>
</MenuItem.Icon>
</MenuItem>
<MenuItem Command="Copy" Header="Copy">
<MenuItem.Icon>
<Viewbox Width="16" Height="16">
<TextBlock FontFamily="{DynamicResource IconFont}" Text=""/>
</Viewbox>
</MenuItem.Icon>
</MenuItem>
<MenuItem Command="Paste" Header="Paste">
<MenuItem.Icon>
<Viewbox Width="16" Height="16">
<TextBlock FontFamily="{DynamicResource IconFont}" Text=""/>
</Viewbox>
</MenuItem.Icon>
</MenuItem>
<CollectionContainer Collection="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TextBox}, Path=Extensions.ExtendCommands}"/>
</CompositeCollection>
</ContextMenu.ItemsSource>
</ContextMenu>
</Setter.Value>
</Setter>
My Attached property :
#region ExtendCommands dependency property
public static IEnumerable GetExtendCommands(DependencyObject obj)
{
return (IEnumerable)obj.GetValue(ExtendCommandsProperty);
}
public static void SetExtendCommands(DependencyObject obj, IEnumerable value)
{
obj.SetValue(ExtendCommandsProperty, value);
}
// Using a DependencyProperty as the backing store for ExtendCommands. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ExtendCommandsProperty =
DependencyProperty.RegisterAttached("ExtendCommands", typeof(IEnumerable), typeof(Extensions), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));
#endregion
Thanks
Upvotes: 7
Views: 1292
Reputation: 7325
Bad news: CollectionContainer has no DataContext. In binding you can only use a Source={x:reference XXX}. XXX must be initialized outside your style/resource dictionary.
To bind something, that has DataContext to attached property of a TextBox is: Set TextBox as DataContext for ContextMenu. So you can use a PlacementTarget property, since your context menu hangs on your TextBox. Further you can normally bind.
<ContextMenu x:Name="uiContexMenu" DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
<ComboBox ItemsSource="{Binding Path=(local:Extensions.ExtendCommands)}"/>
...
</ContextMenu>
And of course you have to set your attached property:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
<TextBox Text="***" Style="{StaticResource DefaultTextBox}">
<local:Extensions.ExtendCommands>
<x:Array Type="{x:Type sys:String}">
<sys:String>Text 1</sys:String>
<sys:String>Text 2</sys:String>
<sys:String>Text 3</sys:String>
</x:Array>
</local:Extensions.ExtendCommands>
</TextBox>
Upvotes: 1
Reputation: 334
It´s a general issue with ContextMenu since it does not always have the data context of a supposed parent. For further information read about inheritance context https://blogs.msdn.microsoft.com/nickkramer/2006/08/17/whats-an-inheritance-context/
As mentioned in the comments of said blog post, you probably need to explicitely set the data context of the context menu to the textbox.
Upvotes: 0