1

I have a Dictionary<string, List<WritingMachine>> where the key is the hostname of a machine that writes to a server, and the value is an list of WritingMachine objects (shown below):

public class WritingMachine
{
    public string HostName { get; set; }
    public string Program { get; set; }
    public string Login { get; set; }
    public string Server { get; set; }
}

I'm trying to bind the dictionary to a WPF ListBox; displaying the Hostname (the dictionary's key), and a summary of the WritingMachine list that's associated with that key.

I'm having trouble accessing the properties of the individual WritingMachine elements within the list.

Here's my XAML so far:

<ListBox x:Name="MachineListBox" Margin="10" Grid.Column="0" FontFamily="Consolas" ItemsSource="{Binding Path=MachineDictionary}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Vertical" Margin="5">
                <ContentPresenter Content="{Binding Key}" Margin="0,0,4,0"/>
                <ItemsControl ItemsSource="{Binding Value}" Margin="10,0,0,0">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Vertical" />
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

This results in a listbox that looks like this:

enter image description here

Obviously this is wrong because the WritingMachine list elements are just returning the default ToString. By overriding WritingMachine's ToString I can get the effect I want (more or less):

enter image description here

But this a crap way of doing it... I want to be able to access the individual element properties and arrange them in controls in my ListBox.ItemTemplate using Content="{Binding Value.Server}" or similar.

Any ideas?

1

2 Answers 2

2

For your ItemsControl you need to set an ItemTemplate:

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock>Server: </TextBlock>
                    <TextBlock Text="{Binding Server}"/>
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>

That will get you started.

Sign up to request clarification or add additional context in comments.

2 Comments

Fantastic. Thanks a lot :)
I think this does not support selection of individual item which means each server but it select the whole group which is host name with all servers. How can I achieve the selection of individual item?
0

Set DataContext property for inner control to show WritingMachine properties. Like so :

<StackPanel DataContext="{Binding Value}" Grid.Row="1">

This will change the DataContext to List<WritingMachine> for inner display control, where you can do normal binding. See full XAML code below :

<ListBox x:Name="LbxMachineDictionary" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical" Margin="5">
                        <Grid Width="461" Height="199">
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition Height="4*"/>
                            </Grid.RowDefinitions>
                            <TextBlock HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="{Binding Key}" VerticalAlignment="Top"/>
                            <StackPanel DataContext="{Binding Value}" Grid.Row="1">
                                <TextBlock HorizontalAlignment="Left"  Grid.Row="1" TextWrapping="Wrap" Text="{Binding HostName}" VerticalAlignment="Top"/>
                                <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Program}" VerticalAlignment="Top"/>
                                <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Login}" VerticalAlignment="Top"/>
                                <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Server}" VerticalAlignment="Top"/>
                            </StackPanel>
                        </Grid>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.