There is such a XAML (read the comments in the code):

<ListBox Grid.Row="0" x:Name="lbListOps"> <ListBox.ItemTemplate> <DataTemplate> <Border Margin="5" BorderThickness="1" BorderBrush="SteelBlue" CornerRadius="4" Width="370"> <Grid Margin="3"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" FontWeight="Bold" Text="{Binding NameOps}"/> <ListView Grid.Row="1" ItemsSource="{Binding OpsWindows}"> <ListView.ItemTemplate> <DataTemplate> <Grid> <Grid.ContextMenu> <ContextMenu> <MenuItem Header="Copy Window Name" Click="WindowName_MenuItem_Click"></MenuItem> /* вот в обработчике событий этого контекстного меню */ <MenuItem Header="Copy ID"></MenuItem> </ContextMenu> </Grid.ContextMenu> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> /* нужно обратиться к этим TextBlock'ам */ <TextBlock Grid.Column="0" Text="{Binding Path=Name}" FontWeight="Bold"></TextBlock> <TextBlock Grid.Column="1" Padding="3 0 0 0" Text="{Binding Path=TeamViewerId}"> </TextBlock> </Grid> </DataTemplate> </ListView.ItemTemplate> </ListView> </Grid> </Border> </DataTemplate> </ListBox.ItemTemplate> </ListBox> 

I know that there is a Sender in the handlers and I need to use it somehow, but I do not know the name TextBlock.

    1 answer 1

    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]; // можно пользоваться } 
    • Those. Can I spawn such commands and "bind" in any element to access the desired element? - cyberdream
    • one
      @cyberdream: Of course! - VladD September