Bind to a listbox, but only show the selected element?
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 ch开发者_Go百科ecks the IsSelected attribute -- and if not selected collapses... but I'm still interested in other ideas.
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>
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>
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}"/>
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.
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.
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.
精彩评论