Porady: znajdowanie elementów generowanych przez DataTemplate
W tym przykładzie pokazano, jak znaleźć elementy generowane przez element DataTemplate.
Przykład
W tym przykładzie istnieje element ListBox powiązany z niektórymi danymi XML:
<ListBox Name="myListBox" ItemTemplate="{StaticResource myDataTemplate}"
IsSynchronizedWithCurrentItem="True">
<ListBox.ItemsSource>
<Binding Source="{StaticResource InventoryData}" XPath="Books/Book"/>
</ListBox.ItemsSource>
</ListBox>
W programie ListBox są używane następujące elementy DataTemplate:
<DataTemplate x:Key="myDataTemplate">
<TextBlock Name="textBlock" FontSize="14" Foreground="Blue">
<TextBlock.Text>
<Binding XPath="Title"/>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
Jeśli chcesz pobrać TextBlock element wygenerowany przez DataTemplate element określonego ListBoxItemelementu , musisz pobrać ListBoxItemelement , znaleźć ContentPresenter w tym ListBoxItemelemecie , a następnie wywołać FindName element ustawiony DataTemplate na tym ContentPresenterobiekcie . W poniższym przykładzie pokazano, jak wykonać te kroki. W celach demonstracyjnych ten przykład tworzy pole komunikatu zawierające zawartość tekstową DataTemplatebloku -generated text.
// Getting the currently selected ListBoxItem
// Note that the ListBox must have
// IsSynchronizedWithCurrentItem set to True for this to work
ListBoxItem myListBoxItem =
(ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items.CurrentItem));
// Getting the ContentPresenter of myListBoxItem
ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(myListBoxItem);
// Finding textBlock from the DataTemplate that is set on that ContentPresenter
DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
TextBlock myTextBlock = (TextBlock)myDataTemplate.FindName("textBlock", myContentPresenter);
// Do something to the DataTemplate-generated TextBlock
MessageBox.Show("The text of the TextBlock of the selected list item: "
+ myTextBlock.Text);
' Getting the currently selected ListBoxItem
' Note that the ListBox must have
' IsSynchronizedWithCurrentItem set to True for this to work
Dim myListBoxItem As ListBoxItem = CType(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items.CurrentItem), ListBoxItem)
' Getting the ContentPresenter of myListBoxItem
Dim myContentPresenter As ContentPresenter = FindVisualChild(Of ContentPresenter)(myListBoxItem)
' Finding textBlock from the DataTemplate that is set on that ContentPresenter
Dim myDataTemplate As DataTemplate = myContentPresenter.ContentTemplate
Dim myTextBlock As TextBlock = CType(myDataTemplate.FindName("textBlock", myContentPresenter), TextBlock)
' Do something to the DataTemplate-generated TextBlock
MessageBox.Show("The text of the TextBlock of the selected list item: " & myTextBlock.Text)
Poniżej przedstawiono implementację metody FindVisualChild
, która używa VisualTreeHelper metod:
private childItem FindVisualChild<childItem>(DependencyObject obj)
where childItem : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is childItem)
{
return (childItem)child;
}
else
{
childItem childOfChild = FindVisualChild<childItem>(child);
if (childOfChild != null)
return childOfChild;
}
}
return null;
}
Private Function FindVisualChild(Of childItem As DependencyObject)(ByVal obj As DependencyObject) As childItem
For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(obj) - 1
Dim child As DependencyObject = VisualTreeHelper.GetChild(obj, i)
If child IsNot Nothing AndAlso TypeOf child Is childItem Then
Return CType(child, childItem)
Else
Dim childOfChild As childItem = FindVisualChild(Of childItem)(child)
If childOfChild IsNot Nothing Then
Return childOfChild
End If
End If
Next i
Return Nothing
End Function
Zobacz też
.NET Desktop feedback