Reputation: 39
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?
Upvotes: 0
Views: 83
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