2

As in my last question I'm about to re-create an expander + it's toggle button.

Expander Template:

<ControlTemplate TargetType="Expander"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="15"/> </Grid.RowDefinitions> <ContentPresenter x:Name="ContentPresenter" Grid.Row="0"/> <ToggleButton Grid.Row="1" > .... </ToggleButton> </Grid> 

Now when I use this Custom Control in my Main View and add a Control (e.g. a Button):

<custom:FullWidthExpander Width="200" HeaderBackground="Gray"> <Button /> </custom:FullWidthExpander> 

The ToggleButton (which is defined in my Expander Template above) gets overridden by this Button.

4
  • are you sure is overridden and not just hidden by the button? you can use Snoop to look exactly how your control looks like when loaded and running. Commented Jan 21, 2016 at 12:50
  • yep, when snooping my app everything except the ContentPresenter is missing :/ Commented Jan 21, 2016 at 13:11
  • If you put a size to your Button, does it still occur? Button takes all available size so the Auto will be you Expander size probably Commented Jan 21, 2016 at 14:17
  • Where is your ControlTemplate defined at? And am I safe to assume that FullWidthExpander is a custom UserControl? I did a quick test with a normal Expander in just XAML in the MainWindow and it works just fine, so my guess is your problem has something to do with your control hierarchy. Commented Jan 21, 2016 at 15:57

2 Answers 2

2

Are you binding the UserControl.Content to the Expander.Content property?

<!-- define a custom Template for the UserControl FullWidthExpander --> <UserControl.Template> <ControlTemplate TargetType="UserControl"> <!-- be sure to include the Content binding to pass the UC.Content to Expander --> <Expander Content="{TemplateBinding Content}"> <!-- create a custom Template for this Expander --> <Expander.Template> <ControlTemplate TargetType="Expander"> <Grid> <Grid.RowDefinitions> <RowDefinition x:Name="ContentRow" Height="*"/> <RowDefinition Height="20"/> </Grid.RowDefinitions> <ContentPresenter Grid.Row="0" Content="{TemplateBinding Content}"/> <ToggleButton Grid.Row="1" Content="Test Toggle Button" /> </Grid> </ControlTemplate> </Expander.Template> </Expander> </ControlTemplate> </UserControl.Template> 

I did a quick test, and this works fine when using the control like this :

<local:FullWidthExpander> <Button Content="Test Content Button"/> </local:FullWidthExpander> 

enter image description here

I also took a look at your other question, and if you have your ControlTemplate.Triggers here then you will also want to make sure to set Expander.IsExpanded to True in order to view your Content. Your trigger is hiding the top content row if IsExpanded=False, which is the default for an Expander.

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

2 Comments

Thank you for your reply :) - If I got it right this solution is "just a dirty work-around". To clarify, I just wanted to make a reusable Expander with a "new look and feel". You may tell me what would be a best practice solution? (I don't want to insult you by telling it's a work-around - but as far as i understood a usercontrol is not the best thing for my purpose)
@Chill-X In your case, yes it is probably better to just use a custom Template for your Expander than a whole new UserControl, however the core problem would be the same regardless. Its good to know the cause and solution so you don't run into issues like this in the future :)
1

When you do this, it means that the entire contents of the user control is replaced with the content you provided.

<custom:FullWidthExpander Width="200" HeaderBackground="Gray"> <Button /> </custom:FullWidthExpander> 

To get around this you need to host the content little bit differently in your usercontrol

First add a dependency property for the user control

 public object UserControlContent { get { return (object)GetValue(UserControlContentProperty); } set { SetValue(UserControlContentProperty, value); } } public static readonly DependencyProperty UserControlContentProperty = DependencyProperty.Register("UserControlContent", typeof(object), typeof(FullWidthExpander), new PropertyMetadata(null)); 

Then bind this to the contentpresenter in the usercontrol's xaml also define a name for your usercontrol like x:Name="Root".

<Expander Header="My expander header"> <Expander.Template> <ControlTemplate> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="15"/> </Grid.RowDefinitions> <ContentPresenter x:Name="ContentPresenter" Grid.Row="0" Content="{Binding UserControlContent, ElementName=Root}" /> <ToggleButton Grid.Row="1" Content="Togglebutton"> </ToggleButton> </Grid> </ControlTemplate> </Expander.Template> </Expander> 

And finally you define the content content in maindwindow xaml as such

<custom:FullWidthExpander> <custom:FullWidthExpander.UserControlContent> <Button Content="Click me"/> </custom:FullWidthExpander.UserControlContent> </custom:FullWidthExpander> 

10 Comments

Thanks for your answer - but I thougth that the ContentPresenter is some sort of "placeholder" for the Content I'm providing?
For templates yes, user controls no.
@JanneMatikainen he never said anything about UserControl
@nkoniishvt that's my fault - The Expander of course is a UserControl. (Thought it's obvious because I said that I' about to create a new Expander). So if I define the design of my Expander inside the main view as a Style / Template with the ContentPresenter as above it will work?
@Chill-X I don't get why you would need a ControlTemplate for a UserControl when you can directly define how it should appear in the .xaml of the UserControl. ControlTemplate are (usually) used for CustomControl, not UserControl
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.