Using xaml to Bind A List Nested In a List to ListViews

Philip Borchert 1 Reputation point
2022-09-13T20:06:50.18+00:00

I have a UserControl that contains two ListViews. The ListView on the left is PLC's the ListView on the Right is the Tags For that PLC. I want to bind in the xaml if all possible. If not binding in the code behind will work.

**PLC Class**  

public class PLC  
{  
 public string Name { get; set; }  
 public ObservableCollection<Tag> Tags { get; set; }  
 public PLC(string name)  
 {  
 Name = name;  
 Tags = new ObservableCollection<Tag>();  
 }  
 public override string ToString()  
 {  
 return Name;  
 }  
}  

Tag Class

public class Tag  
{  
 public Tag(string name, int value)  
 {  
 Name = name;  
 Value = value;  
 }  
 public string Name { get; set; }  
 public int Value { get; set; }  
}  

Relevant Xaml

<UserControl x:Class="Test.UserControls.RuntimeControl"  
             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="450" d:DesignWidth="800">  
    <Grid>  
        <Grid.RowDefinitions>  
            <RowDefinition Height="20"></RowDefinition>  
            <RowDefinition Height="*"></RowDefinition>  
        </Grid.RowDefinitions>  
        <Grid Grid.Row="0">  
            <TextBlock Foreground="Red" Margin="10,0,0,0" >Runtime</TextBlock>  
        </Grid>  
        <Grid Grid.Row="1">  
            <Grid.ColumnDefinitions>  
                <ColumnDefinition Width="*"></ColumnDefinition>  
                <ColumnDefinition Width="*"></ColumnDefinition>  
            </Grid.ColumnDefinitions>  
            <ListView x:Name="PLCLV" Grid.Column="0" Margin="10" FontSize="25" SelectionMode="Single" ScrollViewer.VerticalScrollBarVisibility="Visible"  
                      BorderThickness="0" ItemsSource="{Binding PLCs}">  
                <ListView.ItemTemplate>  
                    <DataTemplate>  
                        <TextBlock Text="{Binding Name}" Foreground="{Binding ForegroundColor}"></TextBlock>  
                    </DataTemplate>  
                </ListView.ItemTemplate>  
            </ListView>  
            <ListView Grid.Column="1" Margin="10" FontSize="25" AlternationCount="2" ScrollViewer.VerticalScrollBarVisibility="Visible"  
                      BorderThickness="0 " **ItemsSource=**Can't Figure This Out**">  
                <ListView.ItemContainerStyle>  
                    <Style TargetType="ListViewItem">  
                        <Setter Property="Focusable" Value="false"/>  
                    </Style>  
                </ListView.ItemContainerStyle>  
                <ListView.ItemTemplate>  
                    <DataTemplate>  
                        <TextBlock>  
                            <Run Text = "Name: "/>  
                            <Run Text =**Can't Figure this out**  
                            <Run Text ="Value: "/>  
                            <Run Text =**Can't Figure this out**  
                        </TextBlock>  
                    </DataTemplate>  
                </ListView.ItemTemplate>  
            </ListView>  
        </Grid>  
    </Grid>  
</UserControl>  

Thank you for your help. I put Can't Figure this out where I need help. The UserControl is getting the DataContext from the parent. So it works but, in the designer with Resharper it complains.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,670 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,226 questions
XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
762 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Hui Liu-MSFT 38,191 Reputation points Microsoft Vendor
    2022-09-14T01:51:33.763+00:00

    Hi, @Philip Borchert .

    If you want to bind two separate ListViews, you could set two Collections.

      <ListView x:Name="PLCLV" Grid.Column="0" Grid.Row="2" Margin="10" FontSize="25" SelectionMode="Single" ScrollViewer.VerticalScrollBarVisibility="Visible"  
                           BorderThickness="0" ItemsSource="{Binding PLCs}">  
                    <ListView.ItemTemplate>  
                        <DataTemplate>  
                            <TextBlock Text="{Binding Name}" Foreground="DarkGreen"></TextBlock>  
                        </DataTemplate>  
                    </ListView.ItemTemplate>  
                </ListView>  
                <ListView Grid.Column="1" Margin="10" FontSize="25" AlternationCount="2" ScrollViewer.VerticalScrollBarVisibility="Visible"  
                           BorderThickness="0 " ItemsSource="{Binding Tags}" >  
                    <ListView.ItemContainerStyle>  
                        <Style TargetType="ListViewItem">  
                            <Setter Property="Focusable" Value="false"/>  
                        </Style>  
                    </ListView.ItemContainerStyle>  
                    <ListView.ItemTemplate>  
                        <DataTemplate>  
                            <TextBlock>  
                                 <Run Text = "Name: "/>  
                                 <Run Text ="{Binding Name}"/>  
                                 <Run Text ="Value: "/>  
                                 <Run Text = "{Binding Value}"/>  
                            </TextBlock>  
                         </DataTemplate>  
                     </ListView.ItemTemplate>  
                 </ListView>  
    

    Codebehind:
    241271-new-text-document-5.txt

    The result:

    241199-image.png

    For Nested Collection, it is generally bound in the following way.

    UserControl:

        <UserControl x:Class="ListViewShowData.UserControls.RuntimeControl"  
                      
                     xmlns:local="clr-namespace:ListBoxNotShowData.UserControls"  
                     xmlns:mw="clr-namespace:ListBoxNotShowData"  
                  >  
            <UserControl.DataContext>  
                <mw:ViewModel/>  
            </UserControl.DataContext>  
            <Grid>  
                <Grid.RowDefinitions>  
                    <RowDefinition Height="20"></RowDefinition>  
                    <RowDefinition Height="*"></RowDefinition>  
                </Grid.RowDefinitions>  
                <Grid Grid.Row="0">  
                    <TextBlock Foreground="Red" Margin="10,0,0,0" >Runtime</TextBlock>  
                </Grid>  
                <Grid Grid.Row="1">  
                    <Grid.ColumnDefinitions>  
                        <ColumnDefinition Width="*"></ColumnDefinition>  
                        <ColumnDefinition Width="*"></ColumnDefinition>  
                    </Grid.ColumnDefinitions>  
                    <ListView x:Name="PLCLV" Grid.Column="0" Margin="10" FontSize="25" SelectionMode="Single" ScrollViewer.VerticalScrollBarVisibility="Visible"  
                               BorderThickness="0" ItemsSource="{Binding PLCs}">  
                        <ListView.ItemTemplate>  
                            <DataTemplate>  
                                <Grid>  
                                    <Grid.ColumnDefinitions>  
                                        <ColumnDefinition/>  
                                        <ColumnDefinition/>  
                                    </Grid.ColumnDefinitions>  
                                    <TextBlock Text="{Binding Name}" Foreground="DarkBlue"></TextBlock>  
                                    <ListView Grid.Column="1" Margin="10" FontSize="25" AlternationCount="2" ScrollViewer.VerticalScrollBarVisibility="Visible"  
                               BorderThickness="0 " ItemsSource="{Binding Tags}">  
                                        <ListView.ItemContainerStyle>  
                                            <Style TargetType="ListViewItem">  
                                                <Setter Property="Focusable" Value="false"/>  
                                            </Style>  
                                        </ListView.ItemContainerStyle>  
                                        <ListView.ItemTemplate>  
                                            <DataTemplate>  
                                                <StackPanel Orientation="Horizontal">  
                                                    <TextBlock Margin="5">  
                                                                <Run Text = "Name: "/>  
                                                                <Run Text = "{Binding Name}"/>  
                                                    </TextBlock>  
                                                    <TextBlock Margin="5">  
                                                                <Run Text = "Value: "/>  
                                                                <Run Text="{Binding Value}"/>  
                                                    </TextBlock>  
          
                                                </StackPanel>  
                                            </DataTemplate>  
                                        </ListView.ItemTemplate>  
                                    </ListView>  
                                </Grid>  
                            </DataTemplate>  
                        </ListView.ItemTemplate>  
                    </ListView>  
                    <ListView x:Name="PLCLV1" Grid.Column="1" Margin="10" FontSize="25" SelectionMode="Single" ScrollViewer.VerticalScrollBarVisibility="Visible"  
                               BorderThickness="0" ItemsSource="{Binding PLCs}">  
                        <ListView.View>  
                            <GridView>  
                                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>  
                                <GridViewColumn Header="Tags">  
                                    <GridViewColumn.CellTemplate>  
                                        <DataTemplate>  
                                            <ListView Grid.Column="1" Margin="10" FontSize="25" AlternationCount="2" ScrollViewer.VerticalScrollBarVisibility="Visible"  
                               BorderThickness="0 " ItemsSource="{Binding Tags}">  
                                                <ListView.ItemContainerStyle>  
                                                    <Style TargetType="ListViewItem">  
                                                        <Setter Property="Focusable" Value="false"/>  
                                                    </Style>  
                                                </ListView.ItemContainerStyle>  
                                                <ListView.ItemTemplate>  
                                                    <DataTemplate>  
                                                        <StackPanel Orientation="Horizontal">  
                                                            <TextBlock Margin="5">  
                                                                <Run Text = "Name: "/>  
                                                                <Run Text = "{Binding Name}"/>  
                                                            </TextBlock>  
                                                            <TextBlock Margin="5">  
                                                                <Run Text = "Value: "/>  
                                                                <Run Text="{Binding Value}"/>  
                                                            </TextBlock>  
                                                             
                                                        </StackPanel>  
                                                    </DataTemplate>  
                                                </ListView.ItemTemplate>  
                                            </ListView>  
                                        </DataTemplate>  
                                    </GridViewColumn.CellTemplate>  
                                </GridViewColumn>  
                            </GridView>  
                        </ListView.View>  
                        
                    </ListView>  
          
                </Grid>  
            </Grid>  
        </UserControl>  
      
    MainWindow.xaml:  
      
        <Window x:Class="ListViewShowData.MainWindow"  
          
                xmlns:local="clr-namespace:ListBoxNotShowData"  
                xmlns:uc="clr-namespace:ListBoxNotShowData.UserControls"  
                mc:Ignorable="d"  
                Title="MainWindow" Height="450" Width="800">  
            <Grid>  
                <uc:RuntimeControl />  
            </Grid>  
        </Window>  
      
    MainWindow.xaml.cs:  
      
        using System.Collections.ObjectModel;  
        using System.Windows;  
          
        namespace ListViewShowData  
        {  
            public partial class MainWindow : Window  
            {  
                public MainWindow()  
                {  
                    InitializeComponent();  
                }  
                 
            }  
            public class ViewModel  
            {  
                public ObservableCollection<PLC> PLCs { get; set; } = new ObservableCollection<PLC>();  
                public ViewModel()  
                {  
                    PLCs.Add(new PLC() { Name = "plc1", Tags = new ObservableCollection<Tag>() { new Tag("name1", 1),new Tag("name2", 2) } } );  
                    PLCs.Add(new PLC() { Name = "plc2", Tags = new ObservableCollection<Tag>() { new Tag("name3", 3),new Tag("name4", 4) } } );  
                }  
            }  
            public class PLC  
            {  
                public string Name { get; set; }  
                public ObservableCollection<Tag> Tags { get; set; }  
                public PLC() { }  
                public PLC(string name)  
                {  
                    Name = name;  
                    Tags = new ObservableCollection<Tag>();  
                }  
            }  
            public class Tag  
            {  
               public Tag()  
               {  
               }  
                public Tag(string name, int value)  
                {  
                    Name = name;  
                    Value = value;  
                }  
                public string Name { get; set; }  
                public int Value { get; set; }  
            }  
        }  
    

    ----------------------------------------------------------------------------

    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.