How to hide/show items in a stack panel?

10,584

Solution 1

You can actually remove the StackPanel completely, as you'll only be showing one UserControl at a time.

Once you've done that, you can use the technique described here to bind the ComboBox's value to the visibility of the UserControl. Just set the Visibility to Collapsed for the UserControl that's not chosen.

This allows you to handle this completely in XAML.

Solution 2

There is always one more way to do it :-)

For example, you can do the very simple way: subscribe to SelectionChanged, check which is the currently selected item, and set the visibility of the items-to-be-hidden to collapsed.

There are more advanced ways, but I doubt that they are needed for this simple task. However, with the development of your code you might need to reconsider using this approach.

Solution 3

This demonstrates two simple ways in which you can use a style to change the visibility on elements based on the selection in a combo box. The first style checks the SelectedIndex of the combo box, and the second checks its SelectedValue. I've populated the combo box with string objects in this example, but you can use SelectedValue with any kind of object, so long as you know what its ToString() method returns.

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:system="clr-namespace:System;assembly=mscorlib">
  <DockPanel>
  <ComboBox x:Name="comboBox" DockPanel.Dock="Top">  
   <system:String>Item 1</system:String>
   <system:String>Item 2</system:String>
  </ComboBox>
  <TextBlock DockPanel.Dock="Top" Text="This displays if Item 1 is selected">
   <TextBlock.Style>
    <Style TargetType="TextBlock">
      <Setter Property="Visibility" Value="Collapsed"/>
      <Style.Triggers>
       <DataTrigger Binding="{Binding ElementName=comboBox, Path=SelectedIndex}" Value="0">
        <Setter Property="Visibility" Value="Visible"/>
       </DataTrigger>
      </Style.Triggers>
    </Style>
   </TextBlock.Style>
  </TextBlock>
  <TextBlock DockPanel.Dock="Top" Text="This displays if Item 2 is selected.">
   <TextBlock.Style>
    <Style TargetType="TextBlock">
      <Setter Property="Visibility" Value="Collapsed"/>
      <Style.Triggers>
       <DataTrigger Binding="{Binding ElementName=comboBox, Path=SelectedValue}" Value="Item 2">
        <Setter Property="Visibility" Value="Visible"/>
       </DataTrigger>
      </Style.Triggers>
    </Style>
   </TextBlock.Style>
  </TextBlock>
  </DockPanel>
</Page>
Share:
10,584
Relativity
Author by

Relativity

A guy with average IQ - still try to explore microsoft .net day by day :)

Updated on June 28, 2022

Comments

  • Relativity
    Relativity almost 2 years

    I have a wpf-mvvm application.

    In that I have follwoing...

    <Combo box>
    item 1
    item 2
    </Combo box>
    <stack pnel>
     <user control 1 />
     <user control 1 />
    </stack pnel>
    

    If user select "item 1" from combo, i need to display "user control 1" If user select "item 2" from combo, i need to display "user control 2"

    In the viewmodel...I have an IList of those two combobox items.

    what is the best way to hid/show items here ?

  • Robert Rossney
    Robert Rossney over 13 years
    Subscribing to events, finding controls in the visual tree, and their properties should be a last resort in WPF, not the first. Using styles and triggers handles most cases like this one, and doesn't require writing (or testing, or maintaining) any code.
  • Vlad
    Vlad over 13 years
    @Robert: just compare the code complexity. Subscribing to the events is trivial, finding a named control is as simple as access by name, setting property through the code is a kindergarten task. The creation of a correct style with the appropriate triggers is more complicated, requires more code and at least intermediate knowledge, and is exactly as good maintainable as code-behind. And I politely disagree with your opinion that XAML code is not a code.
  • Robert Rossney
    Robert Rossney over 13 years
    I think that WPF styles and triggers are fundamental knowledge, not intermediate. XAML is data, not code. It does press Steve McConnell's observation that data is easier to debug than code to its limit, but I still think it applies.
  • Vlad
    Vlad over 13 years
    @Robert: are you serious about debugging? Did you ever try to debug a wrong-behaving trigger? In contrast, debugging a code is a customary and simple activity. During the debugging of code-behind you can always put a breakpoint and inspect the state of any property and any object. I know that triggers ought to be a fundamental knowledge for any WPF practitioner, but as a matter of fact, they are not.
  • Vlad
    Vlad over 13 years
    @Robert: in addition, I find the technique proposed here neither simple nor straightforward (storing information in a tag is somewhat hackish). The solution with code-behind is simpler both conceptually and in terms of the code size (and therefore more maintainable as well).
  • Robert Rossney
    Robert Rossney over 13 years
    Well, we're going to have to agree to disagree. I think that using styles for this kind of thing is basic WPF knowledge, and that this particular pattern (binding controls' Visibility to something) is a fundamental technique. See my answer, which I think is pretty basic.
  • Vlad
    Vlad over 13 years
    @Robert: agreed to disagree :)