I generate UI elements at runtime by using a ItemsControl
. The UI generates successfully but if I am unable to get any properties of the generated UI items, such as "Content" for a label, or SelectedItem
for a ComboBox
. I tried to get these properties by using this tutorial , and these answers but I always get a NullReferenceException
.
The ItemsControl
in XAML looks like this:
<ItemsControl Name="ListOfVideos">
<ItemsControl.Background>
<SolidColorBrush Color="Black" Opacity="0"/>
</ItemsControl.Background>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180"/>
<ColumnDefinition Width="400"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<Image HorizontalAlignment="Left" Height="100" Width="175" x:Name="VideoThumbnailImage" Stretch="Fill" Source="{Binding VideoThumbnailURL}" Grid.Column="0"></Image>
<Label x:Name="VideoTitleLabel" Content="{Binding VideoTitleText}" Foreground="White" Grid.Column="1" VerticalAlignment="Top" FontSize="16" FontWeight="Bold"></Label>
<Label x:Name="VideoFileSizeLabel" Content="{Binding VideoTotalSizeText}" Foreground="White" FontSize="14" Grid.Column="1" Margin="0,0,0,35" VerticalAlignment="Bottom"></Label>
<Label x:Name="VideoProgressLabel" Content="{Binding VideoStatusText}" Foreground="White" FontSize="14" Grid.Column="1" VerticalAlignment="Bottom"></Label>
<ComboBox x:Name="VideoComboBox" SelectionChanged="VideoComboBox_SelectionChanged" Grid.Column="2" Width="147.731" Height="20" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,50" ItemsSource="{Binding VideoQualitiesList}"></ComboBox>
<Label Content="Video Quality" Foreground="White" FontSize="14" VerticalAlignment="Top" Grid.Column="2" HorizontalAlignment="Center"></Label>
<Label Content="Audio Quality" Foreground="White" FontSize="14" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,27" Grid.Column="2"></Label>
<Slider x:Name="VideoAudioSlider" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Bottom" Width="147.731" Maximum="{Binding AudioCount}"></Slider>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This is how I generate the UI elements
public class VideoMetadataDisplay
{
public string VideoTitleText { get; set; }
public int AudioCount { get; set; }
public string VideoThumbnailURL { get; set; }
public string VideoStatusText { get; set; }
public string VideoTotalSizeText { get; set; }
public List<string> VideoQualitiesList { get; set; }
}
public partial class PlaylistPage : Page
{
private void GetPlaylistMetadata()
{
List<VideoMetadataDisplay> newList = new List<VideoMetadataDisplay>();
//populate the list
ListOfVideos.ItemsSource = newList;
}
}
And this is how I'm trying to get the properties of the UI elements
public class Utils
{
public 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 void VideoComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
UIElement CurrentItem = (UIElement)ListOfVideos.ItemContainerGenerator.ContainerFromItem(ListOfVideos.Items.CurrentItem);
Utils utils = new Utils();
ContentPresenter CurrentContentPresenter = utils.FindVisualChild<ContentPresenter>(CurrentItem);
DataTemplate CurrentDataTemplate = CurrentContentPresenter.ContentTemplate;
Label VideoTitle = (Label)CurrentDataTemplate.FindName("VideoTitleLabel", CurrentContentPresenter);
string VideoTitleText = VideoTitle.Content.ToString();
MessageBox.Show(VideoTitleText);
}
Every time I try to run this, FindVisualChild
always returns one of the labels (VideoTitleLabel
) instead of returning the ContentPresenter
for the currently active item. CurrentDataTemplate
is then null and I am unable to get any of the UI elements from it.