Silverlight - Get a DataTemplate control

I have a Silverlight application that uses a DataGrid. Inside this DataGrid, I have a DataTemplate, which is defined as follows:

<Grid x:Name="myGrid" Tag="{Binding}" Loaded="myGrid_Loaded"> <ItemsControl ItemsSource="{Binding MyItems}" Tag="{Binding}"> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal" Width="138"> <TextBlock Text="{Binding Type}" /> <TextBox x:Name="myTextBox" TextChanged="myTextBox_TextChanged" /> </StackPanel> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </Grid> 

When a user enters text in a TextBox, I have an event (myTextBox_TextChanged) that should be fired at that moment. When this event is fired, I would like to get the ItemsControl element, which is the container for this TextBox. How to get this ItemControl from my event handler?

Please note: since the ItemsControl element is located in the DataTemplate DataGrid, I do not believe that I can just add x: Name and refer to it from my code. Or is there a way to do this?

Thanks!

+3
source share
4 answers

Using a combination of ItemsControl.ItemsControlFromItemContainer and VisualTreeHelper.GetParent , you can find your ItemsControl

 var txt = sender as TextBox; var panel1 = VisualTreeHelper.GetParent(txt); var panel2 = VisualTreeHelper.GetParent(panel1); var contentPresenter = VisualTreeHelper.GetParent(panel2); var ic = ItemsControl.ItemsControlFromItemContainer(contentPresenter); 

You may also need to search the Internet for recursive VisualTreeHelper functions to make this easier.

+4
source

I like to have this little extension method in a static class somewhere in my application: -

 public static IEnumerable<DependencyObject> Ancestors(this DependencyObject root) { DependencyObject current = VisualTreeHelper.GetParent(root); while (current != null) { yield return current; current = VisualTreeHelper.GetParent(current); } } 

With this, you can do something like this: -

 ItemsControl control = ((DependencyObject)sender).Ancestors() .TypeOf<ItemsControl>().FirstOrDefault(); 
+4
source

Not sure if this is applicable, but it creates a β€œtoggle button bar” using the same principles.

 private void UIClassButton_Click(object sender, RoutedEventArgs e){ Button SenderButton = (Button)sender; ItemsControl SendersItemControl = ItemsControl.ItemsControlFromItemContainer(VisualTreeHelper.GetParent(SenderButton)); IEnumerable<DependencyObject> DependencyObjectCollection = SendersItemControl.GetContainers(); foreach (ContentPresenter item in DependencyObjectCollection) { ContentPresenter UIClassPresenter = (ContentPresenter)item; Button UIClassButton = (Button)UIClassPresenter.GetVisualChildren().First(); if (UIClassButton != SenderButton) { VisualStateManager.GoToState(UIClassButton, "Normal", true); } else { VisualStateManager.GoToState(UIClassButton, "Pressed", true); } } } 
0
source

Here is an example of capturing the container the ItemsControl is in:

  CheckBox checkbox = sender as CheckBox; foreach (var item in MembersItemsControl.Items) { var container = MembersItemsControl.ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement; UserInformation user = container.DataContext as UserInformation; bool isMale = true; if (user.sex == isMale && checkbox.IsChecked.Value == true) { container.Visibility = System.Windows.Visibility.Visible; } } 

I hope this helps.

0
source

Source: https://habr.com/ru/post/1340125/


All Articles