Jimmyt1988
Jimmyt1988

Reputation: 21156

traversing the xaml document programmatically

I have the following xaml:

<phone:PivotItem Header="MESSAGES" x:Name="Messages">
    ...
    <ListBox x:Name="MessagesStreamList">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid x:Name="ParticipantImages">
                </Grid>

How do I traverse programmatically to get a hold of ParticipantImages so I can programmatically add columns etc?

I do not have direct access to ParticipantImages

---------EDIT-----------

I just tried using the VisualTreeHelper:

int poop = VisualTreeHelper.GetChildrenCount(MessagesStreamList);

but this returns a count of 0.

Is this something to do with the ItemTemplate again?

Upvotes: 0

Views: 131

Answers (2)

aguest
aguest

Reputation: 1

I realize this is a delayed response, but I came across this today when looking for something similar.

My goal was to modify some item's properties within a DataTemplate list box. Here is my structure:

<ListBox ItemsSource="{Binding}" SelectionChanged="Items_SelectionChanged">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>

On selection change, I wanted to modify some properties of the item that was changed. I don't imagine this is the most efficient way but it's what I got.

private void List_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        DependencyObject obj = (DependencyObject)sender;

        obj = loopUntilDesiredTypeIsFound<ListBoxItem>(obj);

        for (int i=0; i<VisualTreeHelper.GetChildrenCount(obj); i++)
        {
            ListBoxItem item = (ListBoxItem)VisualTreeHelper.GetChild(obj,i);
            if (item.IsSelected)
            {
                DependencyObject container = loopUntilDesiredTypeIsFound<Grid>(item);
//here we will have the Grid container for the display objects, such as textblocks, checkboxes, etc..
                break;
            }

        }
    }

    private DependencyObject getChild(DependencyObject obj)
    {
        if (VisualTreeHelper.GetChildrenCount(obj) > 0 )
        {
            return VisualTreeHelper.GetChild(obj, 0);
        }
        return null;
    }

    private DependencyObject loopUntilDesiredTypeIsFound<T>(DependencyObject obj)
    {
        while (obj != null)
        {
            int children = VisualTreeHelper.GetChildrenCount(obj);
            if (getChild(obj) is T)
            {
                return obj;
            }
            obj = getChild(obj);
        }
        return null;
    }

Upvotes: 0

user3690202
user3690202

Reputation: 4055

Because it is in a DataTemplate you cannot get it by name from within the ListBox (or window containing the listbox).

What you can do, is replace the Grid that is inside the data template with a user-control, put the grid into that user control, and then use code inside that user control to get to the Grid.

The user control would be defined as:

<UserControl x:Class="WpfApplication1.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300"
         Loaded="UserControl_Loaded_1">
<Grid x:Name="ParticipantImages">

</Grid>
</UserControl>

And then in code you could do:

    /// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
    }

    private void UserControl_Loaded_1(object sender, RoutedEventArgs e)
    {
        ParticipantImages.Visibility = System.Windows.Visibility.Hidden;
    }
}

Upvotes: 1

Related Questions