Silverlight 4: Как найти исходный элемент пользовательского интерфейса в menuitem_click контекстного меню?

У меня есть сетка данных, и я добавил контекстное меню набора инструментов silverlight 4 в текстовое поле в сетке данных следующим образом. Когда пользователи щелкают правой кнопкой мыши по текстовому полю, отображается контекстное меню. Когда пользователи щелкают по пункту меню с заголовком "Тест", "MenuItem_Click" выполняется. Теперь я хочу получить доступ к текстовому полю из MenuItem_Click и изменить его свойства, такие как фон и т. Д. Есть ли способ найти элемент textbox (который является родителем contextmenu) из события MenuItem_Click?

Мне кажется, что мне не хватает чего-то очень простого.

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

4 ответа

Решение

Там действительно нет необходимости в обходе, это так же просто, как использование привязки данных:

(sender as MenuItem).DataContext as TextBox

Даст вам TextBox, который вы ищете. (Хранение вещей в поле Tag - это не то, чем вы хотите загромождать свой код.)

Все, что я могу предложить, это дать вашему MenuItem тег с именем TextBlock его родителя, например так:EDIT: Не могу понять, как вставить в Xaml, но я уверен, что вы знаете, как это добавить.

Затем в вашем событии клика вы найдете TextBlock:

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

Я обнаружил, что родительским элементом MenuItem является ContextMenu, и это нормально. Но как только вы пытаетесь получить Parent of the ContextMenu, он просто падает.

Хотя я не нашел решения для этого, я нашел несколько обходных путей

  1. Пройдите по визуальному дереву и найдите текстовое поле
  2. Измените код в источниках инструментария управления, чтобы внутренний элемент "Владелец" был представлен как открытое свойство, которое содержит ссылку на владельца контекстного меню, в моем случае - текстового поля.

Интересно, почему ребята из SL инструментария сделали владельца внутренним, а не публичным. Вероятно, их идея состоит в том, чтобы управлять "ContextMenu" только через "ContextMenuService", но, к сожалению, ContextMenuService не дает Владельцу. Надеюсь, ребята из SL инструментария дадут нам возможность получить владельца контекстного меню в будущих выпусках.

Я не уверен, что это работает в Silverlight, но у меня недавно была похожая проблема с WPF. Если вы используете свойство ContextMenu PlacementTarget, оно должно возвращать элемент, который использовался для открытия ContextMenu.

Другие вопросы по тегам