Home > Net >  How to fix ContentControl binding
How to fix ContentControl binding

Time:10-08

I have a very simple program in which a ListBox contains the name of three people. The program should show that person's information (name, age and colour) in the area at the bottom, when you select the name of a person in ListBox. It should, but it doesn't display it:

In the resource section I have a declared a collection of Person class and a DataTemplate that defines how the information of a Person is presented.

The ListBox, listBoxMyFriends, and TextBlock, textBlockMyFriends, bind to the same source (MyFriends), with ListBox using ItemsSource property and TextBlock using ContentControl.
The ContentControl should show the other properties of the person selected.

XAML:

<Window x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Window.Resources>
    <local:Person x:Key="MyFriends" />
    <DataTemplate x:Key="DetailTemplate">
        <Border Width="300" Height="100" Margin="20"
      BorderBrush="Black" BorderThickness="1" Padding="8">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Row="0" Grid.Column="0" Text="Name:"/>
                <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=PersonName}"/>
                <TextBlock Grid.Row="1" Grid.Column="0" Text="Age:"/>
                <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=PersonAge}"/>
                <TextBlock Grid.Row="2" Grid.Column="0" Text="Colour"/>
                <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Path=PersonColour}"/>
            </Grid>
        </Border>
    </DataTemplate>
</Window.Resources>

<StackPanel>
    <TextBlock FontFamily="Verdana" FontSize="11"
           Margin="5,15,0,10" FontWeight="Bold">My Friends:</TextBlock>
    <ListBox Width="200" IsSynchronizedWithCurrentItem="True" Name="listBoxMyFriends"
         ItemsSource="{Binding Source={StaticResource MyFriends}}"/>
    <TextBlock FontFamily="Verdana" FontSize="11" Name="textBlockMyFriends"
           Margin="5,15,0,5" FontWeight="Bold">Information:</TextBlock>
    <ContentControl Content="{Binding Source={StaticResource MyFriends}}"
                ContentTemplate="{StaticResource DetailTemplate}"/>
</StackPanel>

Code Behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Person[] person = { new Person("Bob", 99, "red"),
                            new Person("John", 20, "green"),
                            new Person("Mike", 30, "blue")
        };
        listBoxMyFriends.ItemsSource = person;
    }
}

Person cs.:

public class Person
{
    public string PersonName { get; set; }
    public int PersonAge { get; set; }
    public string PersonColour { get; set; }

    public Person() { }

    public Person(string name, int age, string colour)
    {
        PersonName = name;
        PersonAge = age;
        PersonColour = colour;
    }

    public override string ToString()
    {
        return PersonName.ToString();
    }

}

The information is not displaying when I try to select a person. I think I'm missing something really simple with ContentControl, but I can't figure out what that is.

CodePudding user response:

ContentControl works properly with data it has, but you give it wrong data.

you should bind ContentControl.Content to ListBox.SelectedItem:

<Window.Resources>
    <DataTemplate x:Key="DetailTemplate">
         ...
    </DataTemplate>
</Window.Resources>

<StackPanel>
    <TextBlock FontFamily="Verdana" FontSize="11"
           Margin="5,15,0,10" FontWeight="Bold">My Friends:</TextBlock>
    <ListBox Width="200" IsSynchronizedWithCurrentItem="True" Name="listBoxMyFriends" />

    <TextBlock FontFamily="Verdana" FontSize="11" Name="textBlockMyFriends"
           Margin="5,15,0,5" FontWeight="Bold">Information:</TextBlock>
    <ContentControl Content="{Binding Path=SelectedItem, ElementName=listBoxMyFriends}"
                ContentTemplate="{StaticResource DetailTemplate}"/>
</StackPanel>

resource <local:Person x:Key="MyFriends" /> is redundant. it is just empty instance of Person class, not present in collection. so no reason to display it.

data for display is set in code-behind (listBoxMyFriends.ItemsSource = person;)

  • Related