Feldruebe
Topic Author
Posts: 20
Joined: 24 Jun 2018, 11:52

FindByName fails with custom ContentControl

27 Sep 2022, 11:38

Hello,

I am using a self-made ContentControl with some adjustments (border, images, etc.).
Layouting and Bindings are working fine.
But I struggle to get controls that I place in it by name.
In a parent control, the following call to FindByName gives me null and the actual sizes are 0 when I go manually through the Visual Tree.
It works when I place the Button outside of my content control.

Is there something that I have to look out for or is it a Bug?
            var controlInsideContentControl = (Button)this.FindName("Button1");
            var location1 = controlInsideContentControl.TransformToAncestor(controlInsideContentControl.Parent);
            var location2 = VisualTreeHelper.GetOffset(controlInsideContentControl);
xaml:
<UserControl x:Class="Ui.Controls.BorderPanel.BorderPanelControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:border="clr-namespace:Ui.Controls.BorderPanel"
             mc:Ignorable="d"
             d:DesignWidth="1920"
             d:DesignHeight="1080"
             >
    <Grid>
        <ContentControl Content="{Binding PanelContent, RelativeSource={RelativeSource AncestorType={x:Type border:BorderPanelControl}}}" />
    </Grid>
</UserControl> 
code behind:
#if UNITY_5_3_OR_NEWER
    #define NOESIS
    using Noesis;
#else
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Markup;
#endif

namespace Ui.Controls.BorderPanel
{
    [ContentProperty(nameof(PanelContent))]
    public partial class BorderPanelControl: UserControl
    {
        public static readonly DependencyProperty PanelContentProperty = DependencyProperty.Register(
            nameof(PanelContent), typeof(object), typeof(BorderPanelControl), new PropertyMetadata(default(object)));
        
        public object PanelContent
        {
            get => this.GetValue(PanelContentProperty);
            set => this.SetValue(PanelContentProperty, value);
        }
        
        public BorderPanelControl()
        {
            this.InitializeComponent();
        }

    #if NOESIS
        private void InitializeComponent()
        {
            NoesisUnity.LoadComponent(this);
        }
    #endif
    };
}
Thanks
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: FindByName fails with custom ContentControl

27 Sep 2022, 13:39

Hi, this is happening because the UserControl defines its own NameScope (it is loading an associated xaml to define its appearance), so the content Button can't be registered into the parent control. Instead, implement your BorderPanelControl as a lookless control (no InitializeComponent and no LoadComponent required) and define the appearance as its template:
public class BorderPanelControl : Control { ... }
<Style TargetType="local:BorderPanelControl">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="local:BorderPanelControl">
        <Grid>
          <ContentPresenter Content="{TemplateBinding PanelContent}" />
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>
And consider using the default ContentControl with a custom template if you don't need to define other properties apart from the Content.

Who is online

Users browsing this forum: Bing [Bot] and 34 guests