Question

Is there a way to access the containers generated for an itemscontrol's items?

For example, Given an ItemsControl with an ItemTemplate as shown below, access the actual TextBlock within the DataTemplate generated for each item in the control. (not the object, but its associated textblock).

Views/MainPage.xaml:

<phone:PhoneApplicationPage
    x:Class="PhoneApp1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vm="clr-namespace:PhoneApp1.ViewModels"
    xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.    Toolkit"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <phone:Pivot>
        <phone:Pivot.Resources>
            <vm:PersonViewModel x:Key="ViewModel"/>
        </phone:Pivot.Resources>

        <phone:PivotItem>
            <phone:PivotItem.Header>
                <TextBlock Text="Pivot"/>
            </phone:PivotItem.Header>

            <ItemsControl x:Name="People" DataContext="{StaticResource ViewModel}"     ItemsSource="{Binding People}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock toolkit:SlideInEffect.LineIndex="{Binding PersonLineIndex}"     Text="{Binding Name}"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </phone:PivotItem>

        <phone:PivotItem>
            <phone:PivotItem.Header>
                <TextBlock Text="Empty Pivot"/>
            </phone:PivotItem.Header>
        </phone:PivotItem>
    </phone:Pivot>

</phone:PhoneApplicationPage>

Views/MainPage.xaml.cs

using Microsoft.Phone.Controls;

namespace PhoneApp1
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }
    }
}

ViewModels/PersonViewModel.cs

using PhoneApp1.Models;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace PhoneApp1.ViewModels
{
    public class PersonViewModel
    {
        public PersonViewModel()
        {
            People = new ObservableCollection<Person>
            {
                new Person { Name = "Joe" },
                new Person { Name = "Jack" },
                new Person { Name = "James" },
                new Person { Name = "John" }
            };

            PersonLineIndex = new List<int>();
            for (int i = 0; i < People.Count; i++)
            {
                PersonLineIndex.Add(i);
            }
        }

        public ObservableCollection<Person> People { get; set; }

        public List<int> PersonLineIndex { get; set; }
    }
}

Models/Person.cs:

namespace PhoneApp1.Models
{
    public class Person
    {
        public string Name { get; set; }
    }
}

Why would I need this access? For example: Try to set a different line index for each textblock. Without adding a "LineIndex" property to your Person (as that would violate MVVM).

Was it helpful?

Solution

I figured it out. You would access such ItemsControl's ItemContainerGenerator

public partial class MainPage : PhoneApplicationPage
{
    // Constructor
    public MainPage()
    {
        InitializeComponent();

        People.Loaded += People_Loaded;
    }

    void People_Loaded(object sender, System.Windows.RoutedEventArgs e)
    {
        for (int i = 0; i < People.Items.Count; i++)
        {
            var container = People.ItemContainerGenerator.ContainerFromIndex(i);
            container.SetValue(SlideInEffect.LineIndexProperty, i);
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top