英文:
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:
<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?
答案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 = ...;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论