0
votes

I want to reuse a control, but one of the scenarios requires a context menu and the others do not. Here's my attempt.

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();
        }
    }

And in the XAML to use the Property:

<ctls:RP8Grid UseContextMenu="False"/>

Now the part I cannot square away, how do I access UseContextMenu inside the UserControl? I Have tried the following:

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

with results:

Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl', AncestorLevel='1'

1
You are right, I think I hit propa instead of propdp. My first implementation. RelativeSource, then up thru the ancestor chain?markokstate
<ContextMenu IsEnabled={Binding UseContextMenu, RelativeSource={RelativeSource AncestorType=UserControl}}" />15ee8f99-57ff-4f92-890c-b56153
Couldn't find, have updated the question with my attemptmarkokstate
Right, ContextMenus are out of the visual tree; my bad. I was able to do this with a binding proxy (that answer illustrates doing something else with one). However, disabling a contextmenu is problematic: It still opens, but with all its items disabled -- and it doesn't close properly. It might be better to give your DataGrid a Style which assigns it the context menu when that property is true.15ee8f99-57ff-4f92-890c-b56153
Ah, good idea. I'll check out this proxy, thank you.markokstate

1 Answers

3
votes

If what you want is just to get rid of the ContextMenu at times, this will work:

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