tags:

views:

464

answers:

2

Hi

I have a stackpanel with multiple expanders:

<StackPanel Margin="0,10,0,0">
    <Expander Header="Test 1">
     <ListBox>
      <ListBoxItem Content="Unit 1"/>
      <ListBoxItem Content="Unit 2"/>
     </ListBox>
    </Expander>

    <Expander Header="Test 2">
     <ListBox>
      <ListBoxItem Content="Unit 3"/>
      <ListBoxItem Content="Unit 4"/>
     </ListBox>
    </Expander>
</StackPanel>

And i want to implement these behaviors:

  • one or both expander(s) could be expanded
  • only one expander could be active (change header background)
  • the active expander will change if i select another expander inside the panel however if i select other expander or other controls outside of the panel the active expander stays

How can i achieve this?

A: 

Add them to a ListControl instead of a StackPanel. ListControls support selecting an item.

XAML:

<Window x:Class="ExpanderTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">

    <Window.Resources>

        <Style TargetType="ListBoxItem">
            <Style.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red"/>
                <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Red"/>
            </Style.Resources>

        </Style>

    </Window.Resources>

    <StackPanel Margin="0,10,0,0">
        <ListBox SelectedIndex="1">
            <ListBoxItem HorizontalContentAlignment="Stretch">
                <Expander Header="Test 1">
                    <ListBox>
                        <ListBoxItem Content="Unit 1"/>
                        <ListBoxItem Content="Unit 2"/>
                    </ListBox>
                </Expander>
            </ListBoxItem>
            <ListBoxItem HorizontalContentAlignment="Stretch">
                <Expander Header="Test 2" >
                    <ListBox>
                        <ListBoxItem Content="Unit 3"/>
                        <ListBoxItem Content="Unit 4"/>
                    </ListBox>
                </Expander>
            </ListBoxItem>
        </ListBox>
    </StackPanel>

</Window>

Code behind:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace ExpanderTest
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            EventManager.RegisterClassHandler(typeof(UIElement),
                                         GotFocusEvent,
                                         new RoutedEventHandler(OnGotFocus));
        }

        private static void OnGotFocus(object sender, RoutedEventArgs e)
        {
            // Check if element that got focus is contained by a listboxitem and
            // in that case selected the listboxitem.

            DependencyObject parent = e.OriginalSource as DependencyObject;
            while (parent != null)
            {
                ListBoxItem clickedOnItem = parent as ListBoxItem;
                if (clickedOnItem != null)
                {
                    clickedOnItem.IsSelected = true;
                    return;
                }

                parent = VisualTreeHelper.GetParent(parent);
            }
        }
    }
}

See my answer to this post what the code behind does: link text

Wallstreet Programmer
A: 

I have another problem regarding expander. That is, i have a user control and in it i have an expander.

<UserControl>
  <Expander>
    <ContentControl Content="{Binding}">
  </Expander>
</UserControl>

If i use this user control e.g. like this it works:

<uc:MyControl>
  <ListBox>
    <ListBoxItem Content="Content 1">
  </ListBox>
</uc:MyControl>

However if i use it a control template e.g. like this, it doesn't work:

<ControlTemplate x:key="MyTemplate" TargetType="{x:Type CheckBox}">
  <uc:MyControl Content="{TemplateBinding Content}"/>
</ControlTemplate>

<RadioButton>
  <ListBox>
    <ListBoxItem Content="Content 1">
  </ListBox>
</RadioButton>

I get an error "... already sub element of another element..."

Sys
You need to post this as a separate question.
Wallstreet Programmer