locked
Multiple ContentPresenters in content control's ControlTemplate

    Question

  • I have a custom control, that is inheriting ContentControl and have Content property (it is inheriting AppBarButton actually).

    That control have several dependency properties (Icon, Content, Description + template and template selector properties for each), that I want to bind in the control's ControlTemplate.

    ControlTemplate as follows (truncated for simplicity):

        <ControlTemplate x:Key="IconButtonControlTemplate" TargetType="local:IconButton">
            <Grid x:Name="RootGrid">
                    <StackPanel x:Name="ButtonStack"
                                Transitions="{TemplateBinding ContentTransitions}"
                                Margin="{TemplateBinding Padding}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                Orientation="{TemplateBinding IconToContentOrientation}">
    
                        <ContentPresenter x:Name="IconPresenter"
                                          Content="{TemplateBinding Icon}"
                                          ContentTransitions="{TemplateBinding ContentTransitions}" />
    
                        <StackPanel x:Name="ContentStack" Orientation="{TemplateBinding ContentToDescriptionOrientation}">
    
                            <ContentPresenter x:Name="ContentPresenter"
                                              Content="{TemplateBinding Content}"
                                              ContentTemplate="{TemplateBinding ContentTemplate}"
                                              ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
                                              ContentTransitions="{TemplateBinding ContentTransitions}"
                                              AutomationProperties.AccessibilityView="Raw"/>
                            <ContentPresenter x:Name="DescriptionPresenter"
                                              Content="{TemplateBinding Description}"
                                              ContentTemplate="{TemplateBinding DescriptionTemplate}"
                                              ContentTemplateSelector="{TemplateBinding DescriptionTemplateSelector}"
                                              ContentTransitions="{TemplateBinding ContentTransitions}" />
                        </StackPanel>
    
                    </StackPanel>
    
            </Grid>
        </ControlTemplate>

    The problem is that when I set the Content property of my button, it affects all three ContentPresenters in the template. Every ContentPresenter shows the same content - what's set to the "Content" property.

    If I do not set the Content property, the template works as expected. But when I set it, all ContentPresenters shows the same.

    The dependency properties bound are normal dependency properties with "new PropertyMetadata(Nothing)". Bindings are OK, I've tried to use normal Binding with RelativeSource TemplatedParent and attached debugconvertor to it, the bindings works as expected, but the issue remains.

    Have you face such a issue and does anybody knows how to tackle it?


    Wednesday, November 26, 2014 3:33 PM

Answers

  • Hi Tsvetelin,

    According to my research, ContentPresenter has a feature that will search for the default value if you do not provide the binding content. ContentPresenter get the content property in control XAML as default behavior. You can see more information in Remarks section from http://msdn.microsoft.com/en-us/library/windows/apps/hh920267.aspx.

    So here are two work around.

    The first one is to provide a default value for the Dependency Property, if you cannot provide the value in control XAML, then system will use this default value. Code snippet looks like the following.

    public static readonly DependencyProperty IconProperty =DependencyProperty.Register(
                "Icon",
                typeof(String),
                typeof(IconButton), new PropertyMetadata("Default ICON")
                );
    public static readonly DependencyProperty DescriptionProperty =
                DependencyProperty.Register(
                "Description",
                typeof(String),
                typeof(IconButton), new PropertyMetadata("Default Description"));
    

    The second one is to use other control like “TextBlock”, this control has no feature like ContnetPresenter. If you don’t provide the value in XAML. It will keep null.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.


    Tuesday, December 2, 2014 6:10 AM
    Moderator

All replies

  • Hi Tsvetelin Pavlov,

    I can reproduce your problem in my project. I can see the three ContentPresenters were set to the same content if I just give value to content property. Usually I see one ContentPresenter in control template, I don’t know why you put three ContentPresenters and I cannot find any useful references about this scenario. Did you have some reasons to do so?

    An easiest way to work around this problem is keep one ContentPresenter and change the other two to TextBlock. I have tested this and it worked as expected.

    Please feel free to let me know if you have any concerns.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.

    Thursday, November 27, 2014 6:39 AM
    Moderator
  • I want to make several regions in my control in order to display caption, some additional content and an icon. I want the additional content (let's call it subcontent) to be a little bit more universal - i.e. in one instance of the button to be able to put text there, but on other instance to be able to put progress bar there... The icon might be SymbolIcon or PathIcon or just raster image...

    If I do not use the Content property, everything goes well, but if I set it every ContentPresenter in the template takes its value. What's so special with that Content property?

    If no binding is assigned to the Content property of the ContentPresenter by default it takes the Content property of the control, but I've expected that when a binding is specified it will not act like this.



    Monday, December 1, 2014 12:16 PM
  • Hi Tsvetelin,

    According to my research, ContentPresenter has a feature that will search for the default value if you do not provide the binding content. ContentPresenter get the content property in control XAML as default behavior. You can see more information in Remarks section from http://msdn.microsoft.com/en-us/library/windows/apps/hh920267.aspx.

    So here are two work around.

    The first one is to provide a default value for the Dependency Property, if you cannot provide the value in control XAML, then system will use this default value. Code snippet looks like the following.

    public static readonly DependencyProperty IconProperty =DependencyProperty.Register(
                "Icon",
                typeof(String),
                typeof(IconButton), new PropertyMetadata("Default ICON")
                );
    public static readonly DependencyProperty DescriptionProperty =
                DependencyProperty.Register(
                "Description",
                typeof(String),
                typeof(IconButton), new PropertyMetadata("Default Description"));
    

    The second one is to use other control like “TextBlock”, this control has no feature like ContnetPresenter. If you don’t provide the value in XAML. It will keep null.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.


    Tuesday, December 2, 2014 6:10 AM
    Moderator