Получить элемент из шаблона в ItemsControl - PullRequest
2 голосов
/ 23 марта 2011

У меня есть ItemsControl, который заполнен наблюдаемой коллекцией некоторых классов ViewModel, например:

<ItemsControl ItemsSource="{Binding MyCollection}">
  <ItemsControl.ItemTemplate>
    <DataTemplate Type="{x:Type local:MyViewModel}">
      <Button Content="{Binding ActionName}" Click="ClickHandler"/>
    </DataTemplate>
  <ItemsControl.ItemTemplate>
</ItemsControl>

Отлично работает, отлично выглядит, но не могу понять, как получить«ClickHandler», чтобы знать о классе «MyViewModel», который представлен шаблоном данных.Вот!

private void ClickHandler(object sender, RoutedEventArgs e)
{
  // The 'sender' is the button that raised the event.  Great!
  // Now how do I figure out the class (MyViewModel) instance that goes with this button?
}

Ответы [ 2 ]

7 голосов
/ 23 марта 2011

ОК, я почти сразу понял, что это «DataContext» «отправителя». Я собираюсь оставить это, если сообщество не считает, что этот вопрос слишком очевиден.

private void ClickHandler(object sender, RoutedEventArgs e)
{
  // This is the item that you want.  Many assumptions about the types are made, but that is OK.
  MyViewModel model = ((sender as FrameworkElement).DataContext as MyViewModel);
}
4 голосов
/ 23 марта 2011

Ваш собственный ответ поможет вам в этом конкретном случае.Вот еще один метод, который, хотя и гораздо более сложный, также будет работать в любом сценарии, независимо от сложности:

Начиная с sender (то есть Button), используйте VisualTreeHelper.GetParentпока вы не найдете ContentPresenter.Это тип UIElement, в котором указан ItemTemplate, который вы указали для каждого из ваших предметов.Давайте поместим это ContentPresenter в переменную cp.( Важно: если ваш ItemsControl был ListBox, то вместо ContentPresenter мы бы искали ListBoxItem и т. Д. ).

Затем позвоните ItemsControl.ItemContainerGenerator.ItemFromContainer(cp).Чтобы сделать это, вам нужно иметь некоторую ссылку на конкретный ItemsControl, но это не должно быть сложно - вы можете, например, дать ему Name и использовать FrameworkElement.FindName изВаш взгляд сам.Метод ItemFromContainer вернет вашу ViewModel.

Все это я узнал из глупо полезных и откровенных сообщений Dr. WPF .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...