aluzi992
aluzi992

Reputation: 39

The custom control not working when Window contain two or more this controls(WinUI3)

In WinUI3 project, I create a custom control, contain a Ellipse and I use it's "Fill" property to display image, plus a TextBlock control to display name. The xaml code is:

    <Style TargetType="local:BINPersonPicture2" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:BINPersonPicture2">
                    <Grid 
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                        <Ellipse>
                            <Ellipse.Fill>
                                <ImageBrush x:Name="portraitBrush" ImageSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=PortraitUrl}" Stretch="UniformToFill" />
                            </Ellipse.Fill>
                        </Ellipse>
                        <TextBlock Text="{TemplateBinding PersonName}" FontSize="14" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

C# code is:

    public sealed class BINPersonPicture2 : Control
    {
        bool errorPlaceholderSetted = false;
        public ImageSource PortraitUrl
        {
            get => (ImageSource)GetValue(PortraitUrlProperty);
            set => SetValue(PortraitUrlProperty, value);
        }

        public string PersonName
        {
            get => (string)GetValue(PersonNameProperty);
            set => SetValue(PersonNameProperty, value);
        }

        public ImageSource ErrorPlaceholder
        {
            get => (ImageSource)GetValue(ErrorPlaceholderProperty);
            set => SetValue(ErrorPlaceholderProperty, value);
        }
        DependencyProperty PortraitUrlProperty = DependencyProperty.Register(nameof(PortraitUrl), typeof(ImageSource), typeof(BINPersonPicture2), new PropertyMetadata(default(ImageSource), new PropertyChangedCallback(OnPortraitUrlChanged)));
        DependencyProperty PersonNameProperty = DependencyProperty.Register(nameof(PersonName), typeof(string), typeof(BINPersonPicture2), new PropertyMetadata(default(string), new PropertyChangedCallback(OnPersonNameChanged)));
        DependencyProperty ErrorPlaceholderProperty = DependencyProperty.Register(nameof(ErrorPlaceholder), typeof(ImageSource), typeof(BINPersonPicture2), new PropertyMetadata(default(ImageSource), new PropertyChangedCallback(OnErrorPlaceholderChanged)));

        public BINPersonPicture2()
        {
            this.DefaultStyleKey = typeof(BINPersonPicture2);
        }

        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            Debug.WriteLine("OnApplyTemplate running..........");            
            if (GetTemplateChild("portraitBrush") is ImageBrush ThisBrush)
            {
                ThisBrush.ImageFailed += (s, e) =>
                {
                    if (!errorPlaceholderSetted)
                    {
                        errorPlaceholderSetted = true;
                        if (ErrorPlaceholder != null)
                            ThisBrush.ImageSource = ErrorPlaceholder;
                    }
                };
            }
        }

        private static void OnPortraitUrlChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Debug.WriteLine("OnPortraitUrlChanged running....................");
        }

        private static void OnPersonNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        }

        private static void OnErrorPlaceholderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        }
    }

When I use this control in Window, it works as expected. But If I use two(or more) of this control in a Window:

<local:BINPersonPicture2 Background="MediumSeaGreen" PortraitUrl="{x:Bind TestImageUrl}" Width="100" Height="100" HorizontalAlignment="Right" VerticalAlignment="Bottom"
                                 PersonName="Lily" ErrorPlaceholder="/Assets/portrait.jpg"/>
<local:BINPersonPicture2 Background="Orange" PortraitUrl="{x:Bind TestImageUrl2}" Width="100" Height="100" HorizontalAlignment="Left" VerticalAlignment="Bottom"
                                 PersonName="Tom" ErrorPlaceholder="/Assets/portrait.jpg"/>

The window C# code is:

public string TestImageUrl { get; set; }= "https://images.pexels.com/photos/347926/pexels-photo-347926.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1";
public string TestImageUrl2 { get; set; } = "https://images.pexels.com/photos/672101/pexels-photo-672101.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1";

Build and run this app, I can only see the second control working well, the first control is empty, why? enter image description here

Upvotes: 0

Views: 83

Answers (1)

mm8
mm8

Reputation: 169370

The dependency properties should be defined as static in your BINPersonPicture2 class:

public static DependencyProperty PortraitUrlProperty = DependencyProperty.Register(...);
public static DependencyProperty PersonNameProperty = ...;
public static DependencyProperty ErrorPlaceholderProperty = ...;

Upvotes: 0

Related Questions