Search code examples
wpfxamlattached-properties

Set attached property value on UserControl using element syntax


Suppose I have an attached property "Attached.Template" of type DataTemplate in namespace ns that I wish to set on my UserControl through XAML. Is there a syntax that lets me do this? Here are some things that do not work:

<!-- fails; UserControl may have only one child -->
<UserControl>
   <ns:Attached.Template>
      <DataTemplate />
   </ns:Attached.Template>

   <Grid />
</UserControl>

<!-- fails; the '(' character cannot be included in a name -->
<UserControl>
   <UserControl.(ns:Attached.Template)>
      <DataTemplate />
   </UserControl.(ns:Attached.Template)>

   <Grid />
</UserControl>

<!-- fails; "UserControl.ns" is an undeclared prefix -->
<UserControl>
   <UserControl.ns:Attached.Template>
      <DataTemplate />
   </UserControl.ns:Attached.Template>

   <Grid />
</UserControl>

The property definition is very standard; just following R#'s built-in template:

public static class Attached
{
    public static readonly DependencyProperty TemplateProperty = DependencyProperty.RegisterAttached(
        "Template", typeof(DataTemplate), typeof(Attached),
        new PropertyMetadata(default(DataTemplate)));

    public static void SetTemplate(DependencyObject element, DataTemplate value) =>
        element.SetValue(TemplateProperty, value);

    public static DataTemplate GetTemplate(DependencyObject element) =>
        (DataTemplate) element.GetValue(TemplateProperty);
}

Solution

  • It seems you have to explicitly set the UserControl's Content like this:

    <UserControl>
        <ns:Attached.Template>
            <DataTemplate/>
        </ns:Attached.Template>
    
        <UserControl.Content>
            <Grid/>
        </UserControl.Content>
    </UserControl>
    

    This also works:

    <UserControl>
        <Grid/>
    
        <ns:Attached.Template>
            <DataTemplate/>
        </ns:Attached.Template>
    </UserControl>
    

    IMO a weird bug or imperfection in the XAML Parser.