0

I've defined class trigger which implements the TriggerAction<UIElement>. Inside that class I would like to access the parent of the context menu which is of ContentControl type. So I've defined DependencyProperty of type: ContentControlinside the trigger class.

public class MoveToEditModeTrigger : TriggerAction<UIElement>
    {
        protected override void Invoke(object parameter)
        {
            if (ContentControl == null) return;
            Selector.SetIsSelected(ContentControl, false);
            ContentControl.Focusable = true;
        }

        public ContentControl ContentControl
        {
            get { return (ContentControl)GetValue(ContentControlProperty); }
            set { SetValue(ContentControlProperty, value); }
        }
        public static readonly DependencyProperty ContentControlProperty =
            DependencyProperty.Register("ContentControl", typeof(ContentControl), typeof(MoveToEditModeTrigger), new FrameworkPropertyMetadata(null));
    }

Here is the ContextMenu inside the ContentControl which I want to access from the trigger class:

<ContentControl Name="contentControl">
  <ContentControl.ContextMenu>
    <ContextMenu>
      <MenuItem Header="EditText">
        <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
          <trigger:MoveToEditModeTrigger ContentControl="{Binding ElementName=contentControl}"/>
        </i:EventTrigger>
        </i:Interaction.Triggers>
      </MenuItem>
     </ContextMenu>
  </ContentControl.ContextMenu>
<RichTextBox x:Name="richtxtLeft" Focusable="True" />
</ContentControl>

The problem is that the binding fail, the ContentControl dependency property remains null. I've done that too without success:

ContentControl="{Binding RelativeSource={RelativeSource AncestorType=ContentControl, Mode=FindAncestor}}"

And also tried to use VisualTreeHalper to find the ContentControl. I've also tried to bind to the RichTextBox inside the ContentControl but without any result.

Please, how can I access the ContentControl within the trigger class?

Jacob
  • 3,598
  • 4
  • 35
  • 56
  • The context menu is not in the visual tree of your UI. It is "flying over" your UI and has its own visual tree. – Fratyx Oct 06 '14 at 14:58
  • I understand, how can I bind from it's visual tree to another control in my UI? – Jacob Oct 06 '14 at 15:03
  • 2
    You need to bind to the PlacementTarget property of the ContextMenu. That is the route by which elements in the context menu can reach the visual tree. Often, if you need to get to a specific element, the Tag property is used as a temporary storage for the element in order to make binding simpler. [I believe this is the canonical question on the subject](http://stackoverflow.com/questions/3668654/relativesource-binding-from-a-tooltip-or-contextmenu). If it answers your question, we can mark this as a duplicate (no worries about that). If not, [edit] and state why. –  Oct 06 '14 at 15:14
  • Thank you very nuch ! Yes this is a duplicate question, we can mark is as duplicate. Thank you again. – Jacob Oct 06 '14 at 20:46

1 Answers1

1

The problem is that the context menu, adorners, tooltips, and other elements are not in the application's visual tree, they are in some other layer. For solving this, what I try to do, is to to make the bindings using the datacontext, to make the bindings to the view model, this view model could be the menu's view model (datacontext), or window's view model, maybe the MainViewModel etc.

In this way you could have a list or observable collection with, maybe, MenuViewModels (with a property IsSelected), and an item in the main view model named SelectedMenu or some thing like that. And change the items templates, or data templates according the view models values/data. Hope this tips help.

Raúl Otaño
  • 4,640
  • 3
  • 31
  • 65