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

huangapple go评论69阅读模式
英文:

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

问题

在WinUI3项目中,我创建了一个自定义控件,其中包含一个椭圆(Ellipse),我使用它的“Fill”属性来显示图像,并且使用一个TextBlock控件来显示名称。

以下是XAML代码:

<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#代码如下:

public sealed class BINPersonPicture2 : Control
{
    // ... 其他属性和方法 ...
}

在窗口中使用这个控件时,它按预期工作。但是,如果在窗口中使用两个或更多的此控件时,只有第二个控件正常工作,第一个控件为空。这个问题是什么原因导致的?

英文:

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:

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

C# code is:

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

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

        public ImageSource ErrorPlaceholder
        {
            get =&gt; (ImageSource)GetValue(ErrorPlaceholderProperty);
            set =&gt; 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(&quot;OnApplyTemplate running..........&quot;);            
            if (GetTemplateChild(&quot;portraitBrush&quot;) is ImageBrush ThisBrush)
            {
                ThisBrush.ImageFailed += (s, e) =&gt;
                {
                    if (!errorPlaceholderSetted)
                    {
                        errorPlaceholderSetted = true;
                        if (ErrorPlaceholder != null)
                            ThisBrush.ImageSource = ErrorPlaceholder;
                    }
                };
            }
        }

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

        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:

&lt;local:BINPersonPicture2 Background=&quot;MediumSeaGreen&quot; PortraitUrl=&quot;{x:Bind TestImageUrl}&quot; Width=&quot;100&quot; Height=&quot;100&quot; HorizontalAlignment=&quot;Right&quot; VerticalAlignment=&quot;Bottom&quot;
                                 PersonName=&quot;Lily&quot; ErrorPlaceholder=&quot;/Assets/portrait.jpg&quot;/&gt;
&lt;local:BINPersonPicture2 Background=&quot;Orange&quot; PortraitUrl=&quot;{x:Bind TestImageUrl2}&quot; Width=&quot;100&quot; Height=&quot;100&quot; HorizontalAlignment=&quot;Left&quot; VerticalAlignment=&quot;Bottom&quot;
                                 PersonName=&quot;Tom&quot; ErrorPlaceholder=&quot;/Assets/portrait.jpg&quot;/&gt;

The window C# code is:

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

Build and run this app, I can only see the second control working well, the first control is empty, why?
The custom control not working when Window contain two or more this controls(WinUI3)

答案1

得分: 0

以下是翻译好的部分:

"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 = ...;"

英文:

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 = ...;

huangapple
  • 本文由 发表于 2023年5月17日 15:44:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76269654.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定