绑定到UserControl XAML中的依赖项属性

时间:2017-07-13 17:41:07

标签: c# wpf xaml user-controls dependency-properties

我想重用一个控件,但其中一个场景需要一个上下文菜单而其他场景则不需要。这是我的尝试。

public partial class RP8Grid : UserControl {

    public bool UseContextMenu {
        get { return (bool)GetValue(UseContextMenuProperty); }
        set { SetValue(UseContextMenuProperty, value); }
    }

    // Using a DependencyProperty as the backing store for UseContextMenu.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty UseContextMenuProperty =
        DependencyProperty.Register("UseContextMenu", typeof(bool), typeof(RP8Grid), new PropertyMetadata(false));

        public RP8Grid() {
            InitializeComponent();
        }
    }

在XAML中使用Property:

<ctls:RP8Grid UseContextMenu="False"/>

现在我无法摆脱的部分,如何在UserControl中访问UseContextMenu? 我尝试了以下内容:

<DataGrid>
  <DataGrid.ContextMenu>
    <ContextMenu IsEnabled="{Binding UseContextMenu,RelativeSource={RelativeSource AncestorType=UserControl, Mode=FindAncestor}}">
  </DataGrid.ContextMenu>
</DataGrid>

结果:

  

无法找到与引用&#39; RelativeSource绑定的源代码   FindAncestor,AncestorType =&#39; System.Windows.Controls.UserControl&#39;,   AncestorLevel =&#39; 1&#39;

1 个答案:

答案 0 :(得分:2)

已停用ContextMenu,但已禁用其项目。然后很难让它关闭。如果那是你想要的,我怀疑,binding proxy会让你到那里(见下面的方法的完整版)。

如果您想要的只是偶尔摆脱ContextMenu,这将有效:

<DataGrid 
    >
    <DataGrid.Style>
        <Style TargetType="DataGrid" BasedOn="{StaticResource {x:Type DataGrid}}">
            <Style.Triggers>
                <DataTrigger 
                    Binding="{Binding UseContextMenu, RelativeSource={RelativeSource AncestorType=UserControl}}"
                    Value="True"
                    >
                    <Setter Property="ContextMenu">
                        <Setter.Value>
                            <ContextMenu 
                                >
                                <MenuItem Header="Test Item" />
                                <MenuItem Header="Test Item" />
                                <MenuItem Header="Test Item" />
                                <MenuItem Header="Test Item" />
                            </ContextMenu>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.Style>
</DataGrid>

这是绑定代理版本:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

XAML:

<DataGrid 
    >
    <DataGrid.Resources>
        <local:BindingProxy
            x:Key="UserControlBindingProxy"
            Data="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"
            />
    </DataGrid.Resources>
    <DataGrid.ContextMenu>
        <ContextMenu 
            IsEnabled="{Binding Data.UseContextMenu, Source={StaticResource UserControlBindingProxy}}"
            >
            <MenuItem Header="Test Item" />
            <MenuItem Header="Test Item" />
            <MenuItem Header="Test Item" />
            <MenuItem Header="Test Item" />
        </ContextMenu>
    </DataGrid.ContextMenu>
</DataGrid>