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.

Th1sD0t
  • 1,089
  • 3
  • 11
  • 37
  • are you sure is overridden and not just hidden by the button? you can use [Snoop](https://snoopwpf.codeplex.com/) to look exactly how your control looks like when loaded and running. – KinSlayerUY Jan 21 '16 at 12:50
  • yep, when snooping my app everything except the ContentPresenter is missing :/ – Th1sD0t Jan 21 '16 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 – nkoniishvt Jan 21 '16 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. – Rachel Jan 21 '16 at 15:57

2 Answers2

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.

Community
  • 1
  • 1
Rachel
  • 130,264
  • 66
  • 304
  • 490
  • 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) – Th1sD0t Jan 22 '16 at 06:53
  • @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 :) – Rachel Jan 22 '16 at 14:51
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>
Janne Matikainen
  • 5,061
  • 15
  • 21
  • Thanks for your answer - but I thougth that the ContentPresenter is some sort of "placeholder" for the Content I'm providing? – Th1sD0t Jan 21 '16 at 13:31
  • For templates yes, user controls no. – Janne Matikainen Jan 21 '16 at 14:15
  • @JanneMatikainen he never said anything about UserControl – nkoniishvt Jan 21 '16 at 14:18
  • @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? – Th1sD0t Jan 21 '16 at 14:21
  • @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 – nkoniishvt Jan 21 '16 at 14:23
  • @nkoniishvt I'm still pretty new to WPF programming and as mentioned I'll do strange things because I'm currently learning :) The main reason I wantet to use Templates inside a UserControl was that I waht to make a reusable Control (eg. an expander). – Th1sD0t Jan 21 '16 at 14:28
  • @Chill-X you don't need a Template to make a Control reusable, you only need DependencyProperties. A custom control should be used when you define a new Control that behave like no other Control and isn't a composition of Controls. More information in this answer: http://stackoverflow.com/a/11248415/4049478 – nkoniishvt Jan 21 '16 at 14:36
  • Personally i use a usercontrol when i only have to compose several (already styled/templated) controls into one logical unit, where the appearance of the different controls is independent of the other controls. In case of a custom expander, this is not the case, so i would design a custom control, and a custom control has its own controltemplate. For usercontrols, you don't set a controltemplate (although it is possible since a usercontrol derives from contentcontrol). – Rob van Daal Jan 21 '16 at 16:02
  • Okay, so a UserControl is used for making a "new" Control out of existing ones. As mentioned below, I just wanted to create a reusable Expander with a new look and feel - what would be the best solution for this? A template within my MainView? But this wouldn't be reusable, would it? – Th1sD0t Jan 22 '16 at 06:54
  • You can define the template in application resources. If you somehow need to bind the header & content to be something different then you need to an usecontrol with dependencyproperties which you can bind in the layout as in my example. – Janne Matikainen Jan 22 '16 at 06:59