4

I have a collection of objects which I bind to a ListBox, but I actually only want to display the selected element, and not the entire collection. What's the best way to go about this? Use a different control?

I think I can do a Visibility ValueConverter which checks the IsSelected attribute -- and if not selected collapses... but I'm still interested in other ideas.

patrick
  • 16,091
  • 29
  • 100
  • 164

6 Answers6

7

Since the entire purpose of a ListBox is to display multiple items and provide the user with a way to select them, yes, I'd use a different control.

Or you could do this, which is getting into the territory of stupid:

<ListBox.ItemContainerStyle>
   <Style TargetType="ListBoxItem">
      <Style.Triggers>
         <Trigger Property="IsSelected" Value="false">
            <Setter Property="Visibility" Value="Collapsed"/>
         </Trigger>
      </Style.Triggers>
   </Style>
</ListBox.ItemContainerStyle>
Robert Rossney
  • 94,622
  • 24
  • 146
  • 218
3

While I agree with Anders' answer, there is a way to show only the selected item in an ListBox, if, for some reason beyond my imagination, that's really what you want to do:

<ListBox>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="False">
                    <Setter Property="Visibility" Value="Collapsed" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>
svick
  • 236,525
  • 50
  • 385
  • 514
3

You can get WPF to maintain a "current item" for you without using a ListBox. In fact, if I'm reading this blog post correctly, it automatically does so when you set DataContext to a collection.

You can reference the "current collection item" by using a slash in your Path expression.

Since you've already written your own "Next" and "Previous" buttons (which presumably must already hook into this current-item mechanism), you can do away with the madness of a single-item-at-a-time ListBox, and just bind a TextBlock (or whatever) to the properties of the current item:

<TextBlock Text="{Binding /ItemText}"/>
Joe White
  • 94,807
  • 60
  • 220
  • 330
2

Use a textbox. On your ViewModel (which I suppose you are binding to) create a property exposing the selected element (make sure to implement INotifyPropertyChanged) and bind the textbox to that property.

Anders Abel
  • 67,989
  • 17
  • 150
  • 217
1

I was trying something similar and came up with this neat solution:

<Expander Header="Elements" Name="FooExpander">
                <Expander.HeaderTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="{Binding}"/>
                            <ListBoxItem Content="{Binding ElementName=ElementList, Path=SelectedItem}">
                                <ListBoxItem.Style>
                                    <Style TargetType="ListBoxItem">
                                        <Style.Triggers>
                                            <Trigger Property="Content" Value="">
                                                <Setter Property="Visibility" Value="Collapsed"/>
                                            </Trigger>
                                        </Style.Triggers>
                                    </Style>
                                </ListBoxItem.Style>
                            </ListBoxItem>
                        </StackPanel>
                    </DataTemplate>
                </Expander.HeaderTemplate>
                <ListBox x:Name="ElementList" 
                         SelectionChanged="SelectionChanged" 
                         ItemsSource="{Binding Path=Foo}"
                         DisplayMemberPath="Name"
                         />
            </Expander>

private void SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) {
    FooExpander.IsExpanded = ((sender as ListBox).SelectedIndex == -1);
}

Maybe you find it inspiring.

Daniel Bammer
  • 83
  • 1
  • 6
0

Use a combobox instead of a listbox. A combobox shows only the selected item, but you can still choose an item from the whole list. Also, you can use up/down to move through the list.

Henk van Dijken
  • 249
  • 1
  • 6