views:

654

answers:

4

I have a datagrid and I added silverlight 4 toolkit contextmenu to textbox in datagrid as follows. When users right click on the textbox, contextmenu is being displayed. When users click the menu item with Header "Test", "MenuItem_Click" is getting executed. Now I want to access the textbox from the MenuItem_Click and modify its properties like background etc. Is there anyway to find textbox element(which is contextmenu's parent) from MenuItem_Click event?

It appears to me that I am missing something very simple.

<my:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
    <TextBox Text="{Binding AcctId}"
             Style="{StaticResource documentTextBoxStyle}"
             ToolTipService.ToolTip="Right Click to modify parameters" >
        <toolkit:ContextMenuService.ContextMenu >
            <toolkit:ContextMenu >
                <toolkit:MenuItem Header="Test" Click="MenuItem_Click"/>
            </toolkit:ContextMenu>
        </toolkit:ContextMenuService.ContextMenu>
    </TextBox>
</DataTemplate>

A: 

All I can suggest is giving your MenuItem a Tag with it's parent's TextBlock name like this: EDIT: Can't figure out how to paste in Xaml, but I'm sure you know how to add this.

Then in your click event you find the TextBlock:

private void MenuItem_TextBlockClick(object sender, RoutedEventArgs e)
{
  MenuItem menuItem = (MenuItem)sender;
  TextBlock textBlock = this.FindName((string)menuItem.Tag) as TextBlock;
  /// do something
}

The issue I found was the parent of the MenuItem is ContextMenu, which is fine. But once you try and get the Parent of the ContextMenu it just crashes.

If we give textbox a name, arent we going to have lot of textboxes with the same name because textbox is in datatemplate?
funwithcoding
A: 

Though I did not find a solution to this, I found couple of workarounds

  1. Traverse the visual tree and findout the textbox
  2. Modify the code in control toolkit sources to expose the internal member 'Owner' as a public Property which contains reference to the owner of the context menu, in my case, the textbox.

I wonder why SL toolkit guys made the owner to be internal not public. Probably their idea is to manage 'ContextMenu' only through 'ContextMenuService' but unfortunately ContextMenuService doesnt give the Owner. Hopefully SL toolkit guys will give us a way to get the owner of the context menu in future releases.

funwithcoding
I think the second workaround is cleaner than the first one but requires one to modify the sources of control toolkit and compile to build the dll to include in the project.
funwithcoding
A: 

I'm not sure if this works in Silverlight, but I had a similar issue with WPF recently. If you use the ContextMenu's PlacementTarget property, it should return the element that was used to open the ContextMenu.

rossisdead
+3  A: 

There's really no need for a workaround, it's as simple as using the databinding:

(sender as MenuItem).DataContext as TextBox

Will give you the TextBox you're after. (Storing stuff in the Tag field is really not something you want to clutter your code with.)

Joris