Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get attached property value from content in contentpresenter

I've made a custom window that has a template defined in a resource dictionary. The window has no title bar.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:dsControls="clr-namespace:Something">
<Style x:Key="WindowRegionStyle"
       TargetType="Window">
    /** Other setters **/
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ContentControl">
                <Grid>
                    <Border Background="{StaticResource WindowBackground}"
                            BorderBrush="{StaticResource BorderBrushColor}"
                            BorderThickness="1"
                            CornerRadius="8"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>

                            <Border CornerRadius="8,8,0,0"
                                    BorderBrush="{StaticResource BorderBrushColor}"
                                    Background="{StaticResource HeaderColor}"
                                    Grid.ColumnSpan="2"
                                    Grid.Row="0">
                                <Label Content="{Binding Path=(dsControls:WindowDetails.Title), RelativeSource={RelativeSource TemplatedParent}}"
                                       FontSize="20" />
                            </Border>

                            <ContentPresenter Grid.Row="1" Grid.ColumnSpan="2" Content="{TemplateBinding Content}" />

                        </Grid>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The content that is added to this template is a UserControl. That all works.

But now I want to define a title in the UserControl. To set the title, I made an attached property 'WindowDetails.Title'.

public static class WindowDetails
{
    public static string GetTitle(DependencyObject obj)
    {
        return (string)obj.GetValue(TitleProperty);
    }

    public static void SetTitle(DependencyObject obj, string value)
    {
        obj.SetValue(TitleProperty, value);
    }

    // Using a DependencyProperty as the backing store for Title.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TitleProperty =
        DependencyProperty.RegisterAttached("Title", typeof(string), typeof(WindowDetails), new PropertyMetadata(""));

}

And I set the the title in the UserControl like this:

<UserControl x:Class="Something.View"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:dsControls="clr-namespace:Something"
             Width="400"
             dsControls:WindowDetails.Title="Test">

      /** Some content **/
</UserControl>

The problem

I cannot bind the property value to the label in my template.

What I already tried (and went wrong)

<Label Content="{Binding Path=(dsControls:WindowDetails.Title), RelativeSource={RelativeSource TemplatedParent}}"
                                       FontSize="20" />

and

<Label Content="{Binding Path=(dsControls:WindowDetails.Title), RelativeSource={RelativeSource Self}}"
                                       FontSize="20" />

Also, changing the OwnerType of the Attached property:

  • To WindowDetails

    public static readonly DependencyProperty TitleProperty = DependencyProperty.RegisterAttached("Title", typeof(string), typeof(WindowDetails), new PropertyMetadata(""));

When I do this, the property is not set. But the content of the label has the default property value.

  • To UserControl

    public static readonly DependencyProperty TitleProperty = DependencyProperty.RegisterAttached("Title", typeof(string), typeof(UserControl), new PropertyMetadata(""));

When I do this, the property is set, but the content of the label has no value.

Question

How can I set the attached property in my UserControl and bind it to the content of the label in my template?

Thanks in advance!

Greetings Loetn

like image 851
Loetn Avatar asked Mar 22 '23 03:03

Loetn


1 Answers

This is how you can do this: Give x:Name to your ContentPresenter and refer to it in binding the label.

<Border CornerRadius="8,8,0,0"
   BorderBrush="{StaticResource BorderBrushColor}"
   Background="{StaticResource HeaderColor}"
   Grid.ColumnSpan="2"
   Grid.Row="0">
   <Label Content="{Binding Path=Content.(dsControls:WindowDetails.Title), ElementName="myPresenter"}" FontSize="20" />
</Border>
<ContentPresenter x:Name="myPresenter" Grid.Row="1" Grid.ColumnSpan="2" Content="{TemplateBinding Content}" />
like image 193
Nitin Avatar answered Mar 24 '23 18:03

Nitin