Search code examples
silverlightwindows-phone-7contentpresentervisual-tree

Set the properties of an auto-generated ContentPresenter


Consider the following part of a visual tree in a Windows Phone SL application:

Content presenter

As you can see, a PanoramaItem template contains a reference to a static DataTemplateSelector. It is a simple class that dynamically feeds the data template based on a provided Key, to display different views for different view models provided as DataContext to PanoramaItem. Here is the code for it:

public static T FindResource<T>(this DependencyObject initial, string key) where T : DependencyObject
        {
            DependencyObject current = initial;

            while (current != null)
            {
                if (current is FrameworkElement)
                {
                    if ((current as FrameworkElement).Resources.Contains(key))
                    {
                        return (T)(current as FrameworkElement).Resources[key];
                    }
                }

                current = VisualTreeHelper.GetParent(current);
            }

            if (Application.Current.Resources.Contains(key))
            {
                return (T)Application.Current.Resources[key];
            }

            return default(T);
        }
    }

    public class DataTemplateSelector : ContentControl
    {
        protected override void OnContentChanged(object oldContent, object newContent)
        {
            ContentTemplate = this.FindResource<DataTemplate>(newContent.GetType().FullName);
        }
    }

The problem is that I have no control over the creation of ContentPresenter you can see selected on an image above. To get a consistent layout, I need to be able to set it's Vertical Alignment property. I don't seem to know how I can do it, since I can't reference this ContentPresenter. How can I set a ContentPresenter's properties?


Solution

  • The solution yet again was simple:

    Define a style for my ContentControl derived class:

    <Style TargetType="support:DataTemplateSelector">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="support:DataTemplateSelector">
                            <ContentPresenter
                            ContentTemplate="{TemplateBinding support:DataTemplateSelector.ContentTemplate}"
                            Content="{TemplateBinding support:DataTemplateSelector.Content}" 
                            VerticalAlignment="Top"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
    

    I have defined mine in UserControl.Resources section of a View's XAML.

    The call the "restyling" line of code in the class's constructor:

     public class DataTemplateSelector : ContentControl
        {
            public DataTemplateSelector()
            {
                this.DefaultStyleKey = typeof (DataTemplateSelector);
            } 
    

    And that's how you can control the ContentPresenter element's look of a ContentControl's derived control.