Alexander Ekzarov

<Window ...

xmlnsTongue Tiedx='clr-namespaceTongue Tiedystem.Xml;assembly=System.Xml'

Title='XML Binding'

DataContext='{DynamicResource dataSource}'

>

<Window.Resources>

<XmlDataProvider x:Key='dataSource'>

...

</XmlDataProvider>

<DataTemplate x:Key='Book' DataType='{x:Type sx:XmlElement}'>

...

</DataTemplate>

<DataTemplate x:Key='CD' DataType='{x:Type sx:XmlElement}'>

...

</DataTemplate>

<DataTemplate x:Key='DVD' DataType='{x:Type sx:XmlElement}'>

...

</DataTemplate>

</Window.Resources>

<ListBox

ItemsSource= '{Binding XPath=/Media/*}'>

<ListBox.ItemTemplateSelector>

<l:LocalNameTemplateSelector

xmlns:l='clr-namespace:EssentialWPF' />

</ListBox.ItemTemplateSelector>

</ListBox>

</Window>

My problem is that, each control in ListBoxItem of my ListBox hasn`t Parent property !!!

In another side : How can I get all controls in ListBoxItem All I can get is just Values

ItemContainerGenerator doesn`t help !!!



Re: Windows Presentation Foundation (WPF) DataTemplateSelector problem

Dr. WPF

The Parent property refers to the logical parent... not the visual parent. The elements of a data template are not members of the logical tree. The data item, itself, is the logical node. It's template only makes up its visual appearance. Therefore, if you need to access elements within the template, you need to use the VisualTreeHelper class.

> How can I get all controls in ListBoxItem

You have to use the ItemContainerGenerator to enumerate the ListBoxItems and then use the VisualTreeHelper class to walk the tree.

> ItemContainerGenerator doesn`t help !!!

Can you please explain what you mean If you use the generator correctly, it will definitely provide you access to the visuals within the template.






Re: Windows Presentation Foundation (WPF) DataTemplateSelector problem

Alexander Ekzarov

DependencyObject item = myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items[0]);

item is NULL !!!

But I expected XmlElement or some control.

Another thing is that my listBoxes are on different TabItem-s of TabControl. And VisualTreeHelper can`t see it.





Re: Windows Presentation Foundation (WPF) DataTemplateSelector problem

Dr. WPF

I assume you're saying that myListBox.Items.Count > 0 but the value of the first item is null. In that case, you can use ContainerFromIndex():

Code Block

DependencyObject item = myListBox.ItemContainerGenerator

.ContainerFromIndex(0);

Now if the visuals haven't been generated yet, that's a different problem entirely. Then what you're trying to do doesn't make sense. You would have to wait for the ItemContainerGenerator's status to be ContainersGenerated.

VisualTreeHelper can be used for any visual tree. The class doesn't care that the visuals are on different tab items.






Re: Windows Presentation Foundation (WPF) DataTemplateSelector problem

Alexander Ekzarov

Try this example and you will see, that VisualTreeHelper.GetParent(...) returns not null, only if you are on the same TabItem as control !

Example:

<Window x:Class="Tab.Window1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Window1" Height="300" Width="500">

<Grid>

<DockPanel>

<TabControl x:Name="tabControl" DockPanel.Dock="Top">

<TabItem Header="Tab Item 1" x:Name="tabItem1">

<TextBox x:Name="txtBox1" Width="100" Height="20" />

</TabItem>

<TabItem Header="Tab Item 2" x:Name="tabItem2">

<TextBox x:Name="txtBox2" Width="100" Height="20" />

</TabItem>

</TabControl>

<StackPanel VerticalAlignment="Center">

<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">

<Button HorizontalAlignment="Center" Content="Show me textBox1 parents!" DockPanel.Dock="Bottom" Height="20" Click="Button_Click" />

<Button Margin="10, 0, 0, 0" HorizontalAlignment="Center" Content="Show me textBox2 parents !" DockPanel.Dock="Bottom" Height="20" Click="Button_Click_1" />

</StackPanel>

<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0, 20, 0, 0">

<Button HorizontalAlignment="Center" Content="Show me tabItem1 childs !" DockPanel.Dock="Bottom" Height="20" Click="Button_Click_2" />

<Button Margin="10, 0, 0, 0" HorizontalAlignment="Center" Content="Show me tabItem2 childs !" DockPanel.Dock="Bottom" Height="20" Click="Button_Click_3" />

</StackPanel>

</StackPanel>

</DockPanel>

</Grid>

</Window>

C# code:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

namespace Tab

{

/// <summary>

/// Interaction logic for Window1.xaml

/// </summary>

public partial class Window1 : Window

{

public Window1()

{

InitializeComponent();

}

private void Button_Click(object sender, RoutedEventArgs e)

{

MessageBox.Show((VisualTreeHelper.GetParent(txtBox1) != null).ToString());

}

private void Button_Click_1(object sender, RoutedEventArgs e)

{

MessageBox.Show((VisualTreeHelper.GetParent(txtBox2) != null).ToString());

}

private void Button_Click_2(object sender, RoutedEventArgs e)

{

MessageBox.Show((VisualTreeHelper.GetChildrenCount(tabItem1).ToString()));

}

private void Button_Click_3(object sender, RoutedEventArgs e)

{

MessageBox.Show((VisualTreeHelper.GetChildrenCount(tabItem2).ToString()));

}

}

}