试图模拟图标 属性
Trying to emulate Icon property
我正在开发一个(简单的)用户控件,它显示图像和文本并发布它们的一些属性。
<UserControl.Resources>
<BitmapImage x:Key="defaultImg"
UriSource="/mcWpfLibrary;component/Assets/TagBlue.png"/>
<Thickness x:Key="defaultTxtMargin"
Left="5" Top="0" Right="0" Bottom="0"/>
</UserControl.Resources>
<StackPanel Orientation="Horizontal"
Background="Transparent">
<Image Width="{Binding Path=ImgWidth, ElementName=imageLabel, FallbackValue=24}"
Height="{Binding Path=ImgWidth, ElementName=imageLabel, FallbackValue=24}"
Source="{Binding Path=ImgSource, ElementName=imageLabel, FallbackValue={StaticResource defaultImg}}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
/>
<TextBlock VerticalAlignment="Center"
Text="{Binding Path=LabelText, ElementName=imageLabel, FallbackValue=Demo text}"
FontSize="{Binding Path=LabelFontSize, ElementName=imageLabel, FallbackValue=22}"
FontFamily="{Binding Path=LabelFontFamily, ElementName=imageLabel, FallbackValue=Segoe UI}"
Foreground="{Binding Path=LabelForeground, ElementName=imageLabel, FallbackValue=White}"
Margin="{Binding Path=LabelMargin, ElementName=imageLabel, FallbackValue={StaticResource defaultTxtMargin}}"
Style="{Binding Path=LabelStyle, ElementName=imageLabel}"
TextTrimming="CharacterEllipsis"
/>
</StackPanel>
我正在尝试添加一个图标 属性,类似于 AppBarButton 控件的图标 属性,允许使用文本而不是 URI 分配一些库存图像。
/// <summary>
/// Image Source property
/// </summary>
public ImageSource ImgSource
{
get { return (ImageSource)GetValue(ImageSourceProperty); }
set { SetValue(ImageSourceProperty, value); }
}
public static readonly DependencyProperty ImageSourceProperty =
DependencyProperty.Register("ImgSource", typeof(ImageSource), typeof(LabelImg));
/// <summary>
/// Icon property
/// </summary>
public string Icon
{
get { return (string)GetValue(IconProperty); }
set
{
SetValue(IconProperty, value);
switch (value)
{
case "Document":
ImgSource = new BitmapImage(new Uri("/mcWpfLibrary;component/Assets/AddDocumentBlue.png", UriKind.Relative));
break;
case "Bullets":
ImgSource = new BitmapImage(new Uri("/mcWpfLibrary;component/Assets/BulletsBlue.png", UriKind.Relative));
break;
case "Tag":
ImgSource = new BitmapImage(new Uri("/mcWpfLibrary;component/Assets/TagBlue.png", UriKind.Relative));
break;
}
}
}
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register("Icon", typeof(string), typeof(LabelImg), new PropertyMetadata(""));
如果我使用 XAML 分配一些值,它不起作用:
<jm:LabelImg x:Name="Btn"
LabelText="hello world"
Icon="Bullets"/>
但如果我在代码隐藏中分配一些值,它会正常工作:
private void BtnDoc_Click(object sender, RoutedEventArgs e)
{
Btn.Icon = "Document";
}
有没有办法在XAML中使用它?
问题出在您对图标依赖项的定义中 属性。您需要在 PropertyMetadata 中定义 PropertyChangedCallback。否则,它将不知道如何处理从您的 XAML.
收到的初始值
快速修复:
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register("Icon", typeof(string), typeof(UserControl1), new PropertyMetadata(OnPropertyChanged));
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as <Insert-The-Name-Of-Your-UserControl>;
control.Icon = e.NewValue as string;
}
问题是如何在 XAML 和代码中访问依赖项 属性。
- XAML处理器根本不使用
Icon
属性,它直接访问IconProperty
依赖属性来获取和设置它。
- 如果在代码中设置 属性,则调用
Icon
属性 的 setter,这只是依赖项 [=35] 的便利包装=],所以你不必调用 GetValue
和 SetValue
并且它 不应该超过 因为你在你的问题中描述的原因,不一致XAML 和代码中的行为。
为了解决这个问题,您必须在依赖项 属性 声明中注册一个 property changed callback 并将代码从 Icon
属性 移到那里。每次 属性 更改时都会调用回调,因此设置 Icon
属性 或其依赖项 属性.
的行为相同
/// <summary>
/// Icon property
/// </summary>
public string Icon
{
get { return (string)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register("Icon",
typeof(string),
typeof(LabelImg),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
new PropertyChangedCallback(OnIconChanged)));
private static void OnIconChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var labelImg = (LabelImg)d;
var value = (string)e.NewValue;
switch (value)
{
case "Document":
labelImg.ImgSource = new BitmapImage(new Uri("/mcWpfLibrary;component/Assets/AddDocumentBlue.png", UriKind.Relative));
break;
case "Bullets":
labelImg.ImgSource = new BitmapImage(new Uri("/mcWpfLibrary;component/Assets/BulletsBlue.png", UriKind.Relative));
break;
case "Tag":
labelImg.ImgSource = new BitmapImage(new Uri("/mcWpfLibrary;component/Assets/TagBlue.png", UriKind.Relative));
break;
}
}
我正在开发一个(简单的)用户控件,它显示图像和文本并发布它们的一些属性。
<UserControl.Resources>
<BitmapImage x:Key="defaultImg"
UriSource="/mcWpfLibrary;component/Assets/TagBlue.png"/>
<Thickness x:Key="defaultTxtMargin"
Left="5" Top="0" Right="0" Bottom="0"/>
</UserControl.Resources>
<StackPanel Orientation="Horizontal"
Background="Transparent">
<Image Width="{Binding Path=ImgWidth, ElementName=imageLabel, FallbackValue=24}"
Height="{Binding Path=ImgWidth, ElementName=imageLabel, FallbackValue=24}"
Source="{Binding Path=ImgSource, ElementName=imageLabel, FallbackValue={StaticResource defaultImg}}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
/>
<TextBlock VerticalAlignment="Center"
Text="{Binding Path=LabelText, ElementName=imageLabel, FallbackValue=Demo text}"
FontSize="{Binding Path=LabelFontSize, ElementName=imageLabel, FallbackValue=22}"
FontFamily="{Binding Path=LabelFontFamily, ElementName=imageLabel, FallbackValue=Segoe UI}"
Foreground="{Binding Path=LabelForeground, ElementName=imageLabel, FallbackValue=White}"
Margin="{Binding Path=LabelMargin, ElementName=imageLabel, FallbackValue={StaticResource defaultTxtMargin}}"
Style="{Binding Path=LabelStyle, ElementName=imageLabel}"
TextTrimming="CharacterEllipsis"
/>
</StackPanel>
我正在尝试添加一个图标 属性,类似于 AppBarButton 控件的图标 属性,允许使用文本而不是 URI 分配一些库存图像。
/// <summary>
/// Image Source property
/// </summary>
public ImageSource ImgSource
{
get { return (ImageSource)GetValue(ImageSourceProperty); }
set { SetValue(ImageSourceProperty, value); }
}
public static readonly DependencyProperty ImageSourceProperty =
DependencyProperty.Register("ImgSource", typeof(ImageSource), typeof(LabelImg));
/// <summary>
/// Icon property
/// </summary>
public string Icon
{
get { return (string)GetValue(IconProperty); }
set
{
SetValue(IconProperty, value);
switch (value)
{
case "Document":
ImgSource = new BitmapImage(new Uri("/mcWpfLibrary;component/Assets/AddDocumentBlue.png", UriKind.Relative));
break;
case "Bullets":
ImgSource = new BitmapImage(new Uri("/mcWpfLibrary;component/Assets/BulletsBlue.png", UriKind.Relative));
break;
case "Tag":
ImgSource = new BitmapImage(new Uri("/mcWpfLibrary;component/Assets/TagBlue.png", UriKind.Relative));
break;
}
}
}
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register("Icon", typeof(string), typeof(LabelImg), new PropertyMetadata(""));
如果我使用 XAML 分配一些值,它不起作用:
<jm:LabelImg x:Name="Btn"
LabelText="hello world"
Icon="Bullets"/>
但如果我在代码隐藏中分配一些值,它会正常工作:
private void BtnDoc_Click(object sender, RoutedEventArgs e)
{
Btn.Icon = "Document";
}
有没有办法在XAML中使用它?
问题出在您对图标依赖项的定义中 属性。您需要在 PropertyMetadata 中定义 PropertyChangedCallback。否则,它将不知道如何处理从您的 XAML.
收到的初始值快速修复:
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register("Icon", typeof(string), typeof(UserControl1), new PropertyMetadata(OnPropertyChanged));
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as <Insert-The-Name-Of-Your-UserControl>;
control.Icon = e.NewValue as string;
}
问题是如何在 XAML 和代码中访问依赖项 属性。
- XAML处理器根本不使用
Icon
属性,它直接访问IconProperty
依赖属性来获取和设置它。 - 如果在代码中设置 属性,则调用
Icon
属性 的 setter,这只是依赖项 [=35] 的便利包装=],所以你不必调用GetValue
和SetValue
并且它 不应该超过 因为你在你的问题中描述的原因,不一致XAML 和代码中的行为。
为了解决这个问题,您必须在依赖项 属性 声明中注册一个 property changed callback 并将代码从 Icon
属性 移到那里。每次 属性 更改时都会调用回调,因此设置 Icon
属性 或其依赖项 属性.
/// <summary>
/// Icon property
/// </summary>
public string Icon
{
get { return (string)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register("Icon",
typeof(string),
typeof(LabelImg),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
new PropertyChangedCallback(OnIconChanged)));
private static void OnIconChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var labelImg = (LabelImg)d;
var value = (string)e.NewValue;
switch (value)
{
case "Document":
labelImg.ImgSource = new BitmapImage(new Uri("/mcWpfLibrary;component/Assets/AddDocumentBlue.png", UriKind.Relative));
break;
case "Bullets":
labelImg.ImgSource = new BitmapImage(new Uri("/mcWpfLibrary;component/Assets/BulletsBlue.png", UriKind.Relative));
break;
case "Tag":
labelImg.ImgSource = new BitmapImage(new Uri("/mcWpfLibrary;component/Assets/TagBlue.png", UriKind.Relative));
break;
}
}