2

Im quite new to wpf and have to following problem.

I need to create a List (i am using a listbox) of items that can be expanded (expander). The problem is, that they can be expanded, only if they have been 'selected'. Each listboxitem should have a checkbox and some text.

So very basic example to illustrate what i mean:

<listbox>
<item>(checkbox) John Doe</item>
<item>(checkbox) Mike Murray</item>
</listbox>

If any (so multiple is allowed) of the checkboxes in the listbox are checked, then the item expands showing more data.

Again an example:

<listbox>
<item>
   (checkbox-checked) John Doe
   Some extra data shown in expanded area
</item>
<item>
   (checkbox-unchecked) Mike Murray</item>
</listbox>

I cant get a expander to use a checkbox as 'togglebutton'.

Could anyone help me out? Some example code would be very welcome...

2 Answers 2

2

This should do the trick:

<ListBox>
    <ListBox.Resources>
        <Style TargetType="Expander">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Expander">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>

                            <CheckBox
                                IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
                                Content="{TemplateBinding Header}"
                                />
                            <ContentControl
                                x:Name="body"
                                Grid.Row="1" Content="{TemplateBinding Content}"
                                />
                        </Grid>

                        <ControlTemplate.Triggers>
                            <Trigger Property="IsExpanded" Value="False">
                                <Setter TargetName="body" Property="Visibility" Value="Collapsed" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </ListBox.Resources>

    <Expander Header="One">
        Content one
    </Expander>

    <Expander Header="Two">
        Content two
    </Expander>
</ListBox>

I've defined a Style here that changes the Template of any Expander controls to which the Style is applied. (And since I've put the Style in the ListBox.Resources it'll automatically apply to an Expander controls in the list.)

The trick to getting the CheckBox to work is that when you put it (or indeed any ToggleButton based control) into an Expander template, you need to use a data binding configured with its RelativeSource set to the TemplatedParent. This enables two-way binding - it means that not only does the CheckBox reflect the current state of the expander, it is also able to change the current state.

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

4 Comments

Hi Ian, thank you very much for your reply. I have your example working and also it working (to some extent) in my application. I have another question and hope you could help with it too. Given the setup of the original question, a Listbox with a checkbox as togglebutton, I use it to display a list of customers. My next problem is the following: Some of the customers need to be pre-selected (for example: if a customer is > 18 years old, default = checked, when the form is loaded) Can I do this (and is it possible through binding?)
Yes, definitely possible. I'm assuming you're using an ItemTemplate in practice, and that the Expander is in there. (And if you aren't you should!) In your ViewModel, you'll want a per-item viewmodel class, so your main viewmodel can expose a list it per-item viewmodels to act as the ItemSource of your list. And then, just bind the IsExpanded property of the Expander to a boolean property of the per-item viewmodel.
I dont have a per-item viemodel class for the items in the listbox (yet), I will try that. What i have now is to bind the IsExpanded property of the Expander with a property in the viewmodel of my current form/view, but somehow I can't access/find that property. When I write: IsExpanded="True", it works perfectly. When I write IsExpanded="{Binding Path=PropertyNameThatGivesBooleanForSelected}" (or without Path=) it doesn't work. The property is never read. I will try a per-item viewmodel as you said, but I actually expected what i have now also to work.
I just created a per-item viewmodel as you said, and it works perfect now! Thank very much for your help!
-1

All you need to add a check box in the header is this code:

            <telerik:RadExpander.Header>
                <StackPanel Orientation="Horizontal">
                    <CheckBox VerticalAlignment="Center"/>
                    <TextBlock Margin="5,0,0,0">Legend</TextBlock>
                </StackPanel>
            </telerik:RadExpander.Header>

I am using Rad Control, The same can be done using the standard expander

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.