Binding ContextMenu property to owner property
Asked Answered
M

2

7

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

Machado answered 17/9, 2016 at 9:44 Comment(4)
Add some code here, to make it easy to understandOgg
take a look at this answer:#3879120. PlacementTarget property in context menu is what you want?Ogg
Thanks @Ogg but it not helps. I trying binding to owner attached property!Machado
Could you please show the part of your code where you set the said attached property on the TextBox?Barnaba
S
1

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.

What you can do:

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>
Spiritualty answered 28/3, 2017 at 15:28 Comment(0)
J
0

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.

Jocosity answered 5/10, 2016 at 19:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.