You fit wrong. You can pierce the result with force on your way, but it is better to go differently.
The correct way is this: you are not trying to crawl through the controls and find what you need, but send a command to the VM, and there is access to everything that is needed.
Example.
class OpsWindow : ViewModelBase { public OpsWindow() { WindowNameCopyCommand = new RelayCommand(o => OnWindowNameCopy(); }); } public string Name { get; set; } // тут реализация INotifyPropertyChanged public int TeamViewerId { get; set; } // и тут public ICommand WindowNameCopyCommand { get; } void OnWindowNameCopy() { // тут у вас есть доступ к чему угодно MessageBox.Show(Name); } }
Accordingly, your XAML is corrected to:
<MenuItem Header="Copy Window Name" Command="{Binding WindowNameCopyCommand}"/>
RelayCommand implementation can be found anywhere, for example in your MVVM framework. As a last resort, it was published several times on the site (for example, here ).
For comparison, the same thing implemented using the “get through UI” approach:
void WindowName_MenuItem_Click(object sender, RoutedEventArgs e) { // жёстко прописываем тип элемента MenuItem var item = (MenuItem)sender; // жёстко прописываем тип элемента ContextMenu var menu = (ContextMenu)item.Parent; // жёстко кодируем, что мы в верхней части контекстного меню, и что // родительский элемент - Grid var grid = (Grid)menu.PlacementTarget; // жёстко прописываем индексы дочерних элементов var textblock1 = (TextBlock)grid.Children[0]; var textblock2 = (TextBlock)grid.Children[1]; // можно пользоваться }