Search code examples
wpfbindinglistboxdatatemplate

WPF Listbox w/ DataTemplate Binding Issue


I'm trying to create a ListBox with a custom data template but the bindings seem to be wrong. When I try to add items to the list with the PacketItem template they are added, but the text in the three HexItem textboxes remains blank. When I set the item template of the listbox directly to the HexItem data template that works fine. It only has problems when nested in the PacketItem data template.

I'm sure this is a simple fix, it seems like when the template is nested it doesn't know where to look for the text bindings. I'm thinking binding to a relative source to get the data context from a parent would work, but that seems like the wrong way to do it.

Revised XAML

<UserControl x:Class="wpfPacketBox.ctlPacketBox"
             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" 
             xmlns:local="clr-namespace:wpfPacketBox"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="600">
    <UserControl.Resources>
        <DataTemplate x:Key="PacketItem">
            <Expander IsExpanded="True"
                      d:DesignWidth="600">
                <Expander.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="PacketNum" />
                            <TextBlock Text="Source" />
                            <TextBlock Text="Dest" />
                            <TextBlock Text="PacketID (FF0A)" />
                        </StackPanel>
                    </DataTemplate>
                </Expander.HeaderTemplate>
                <Expander.ContentTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="10*" />
                                <ColumnDefinition Width="65*" />
                                <ColumnDefinition Width="25*" />
                            </Grid.ColumnDefinitions>

                            <Grid Grid.Column="0">
                                <TextBox Text="{Binding Offset}"
                                         FontFamily="Courier New"
                                         Foreground="Blue"
                                         Background="#FFCCCCCC"
                                         TextWrapping="Wrap"
                                         BorderThickness="0" />
                            </Grid>

                            <Grid Grid.Column="1">
                                <TextBox Text="{Binding Hex}"
                                         FontFamily="Courier New"
                                         TextWrapping="Wrap"
                                         BorderThickness="0" />
                            </Grid>

                            <Grid Grid.Column="2">
                                <TextBox Text="{Binding Ascii}"
                                         FontFamily="Courier New"
                                         Background="#FFCCCCCC"
                                         TextWrapping="Wrap"
                                         BorderThickness="0" />
                            </Grid>
                        </Grid>
                    </DataTemplate>
                </Expander.ContentTemplate>
            </Expander>
        </DataTemplate>
    </UserControl.Resources>

    <Grid>
        <ListBox ItemsSource="{Binding Path=Packets}"
                 ItemTemplate="{StaticResource PacketItem}"
                 Grid.Row="1"
                 ScrollViewer.HorizontalScrollBarVisibility="Disabled" />
    </Grid>

</UserControl>

Code

using System;
using System.Windows.Controls;
using System.Collections.ObjectModel;

namespace wpfTester.UserControls
{
    public partial class test : UserControl
    {
        public ObservableCollection<clsPacket> Packets;

        public test()
        {
            InitializeComponent();
            Packets = new ObservableCollection<clsPacket>();
            PacketListBox.ItemsSource = Packets;

            for (int i = 0; i <= 100; i++)
            {
                Packets.Add(new clsPacket() { Offset = i, Hex = "00 11 22 33 44 55 66 77", Ascii = "ABCDEFGH" });
            }
        }
    }

    public class clsPacket
    {
        public long Offset { get; set; }
        public String Hex { get; set; }
        public String Ascii { get; set; }
    }
}

Solution

After some digging I found the solution here. The problem was the expander. I was setting the header/content templates of the expander. But never specified the Header/Content it self. Here's the modified expander tag that fixed my problem.

<Expander IsExpanded="True" Header="{Binding}" Content="{Binding}">

Solution

  • After some digging I found the solution here. The problem was the expander. I was setting the header/content templates of the expander. But never specified the Header/Content it self. Here's the modified expander tag that fixed my problem.

    <Expander IsExpanded="True" Header="{Binding}" Content="{Binding}">