Set the properties of an auto-generated ContentPresenter
-
27-02-2021 - |
Question
Consider the following part of a visual tree in a Windows Phone SL application:
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 2
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.
OTHER TIPS
You seem to already have the answer sitting there in front of you.
Use the VisualTreeHelper.GetParent
to get the direct visual parent of the DataTemplateSelector
as a FrameworkElement
, then modify its VerticalAlignment
property.
BTW :-
if (current is FrameworkElement)
{
if ((current as FrameworkElement).Resources.Contains(key))
{
return (T)(current as FrameworkElement).Resources[key];
}
}
can be reduced to:-
var currentFE = current As FrameworkElement;
if (currentFE != null && currentFE.Contains(key) )
{
return (T)currentFE.Resource[key];
}
Cast attempt only occurs once instead of potentially three times, is shorter and is easier to understand. An example of where adding a variable is beneficial (whereas normally we might try to reduce the number of variables in our code).