将ContextMenu属性绑定到所有者属性

时间:2016-09-17 09:44:42

标签: wpf xaml binding contextmenu attached-properties

我将上下文菜单绑定到textbox的附加属性时遇到问题。所以我有TextBox,右键单击它有一个上下文菜单。那么如何将上下文菜单的属性绑定到WPF XAML中TextBox的附加属性?在这里,我尝试绑定到TextBox,但它没有帮助

 <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>

我的附属财产:

 #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

由于

2 个答案:

答案 0 :(得分:0)

这是ContextMenu的一般问题,因为它并不总是具有假定父级的数据上下文。有关继承上下文https://blogs.msdn.microsoft.com/nickkramer/2006/08/17/whats-an-inheritance-context/

的更多信息,请参阅

正如所述博客文章的评论中所提到的,您可能需要明确地将上下文菜单的数据上下文设置为文本框。

答案 1 :(得分:0)

坏消息: CollectionContainer没有DataContext。在绑定中,您只能使用Source = {x:reference XXX}。必须在样式/资源字典之外初始化XXX。

你能做什么:

要绑定一些东西,将DataContext附加到TextBox的附加属性是: 将TextBox设置为ContextMenu的DataContext。 因此,您可以使用PlacementTarget属性,因为您的上下文菜单会挂起在TextBox上。此外,您通常可以绑定。

<ContextMenu x:Name="uiContexMenu" DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">

<ComboBox ItemsSource="{Binding Path=(local:Extensions.ExtendCommands)}"/>
...
</ContextMenu>

当然,你必须设置附属财产:

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>