标记扩展是XAML中一种特殊的语法机制,允许在属性赋值时动态计算或引用值,而不仅仅是使用简单的文本字符串。它们提供了一种在XAML中灵活处理值的方式,可以实现复杂的赋值逻辑。
StaticResource
用于引用已经定义的资源,通常在资源字典中。
text<Window.Resources> <SolidColorBrush x:Key="PrimaryBrush" Color="Blue"/> </Window.Resources> <Grid Background="{StaticResource PrimaryBrush}"> <!-- 使用静态资源 --> </Grid>
与StaticResource
类似,但会在运行时动态更新资源。
text<Window.Resources> <SolidColorBrush x:Key="ThemeBrush" Color="Green"/> </Window.Resources> <Button Background="{DynamicResource ThemeBrush}"> 动态资源按钮 </Button>
最常用的标记扩展,用于数据绑定。
text<TextBlock Text="{Binding Name, Mode=TwoWay}" /> <!-- 带转换器的绑定 --> <TextBlock Text="{Binding Age, Converter={StaticResource AgeConverter}}" />
引用静态成员(属性、字段或常量)。
text<!-- 引用系统颜色 --> <Border Background="{x:Static SystemColors.ControlBrush}" /> <!-- 引用自定义静态成员 --> <TextBlock Text="{x:Static local:Constants.WelcomeMessage}" />
C#public static class Constants
{
public static string WelcomeMessage => "Welcome to my app!";
public static string AppName => "My WPF Application";
public static string Version => "1.0.0";
// 可以添加其他静态成员
public static Thickness DefaultMargin => new Thickness(10);
public static int MaxItems => 100;
}
显式设置属性为null。
text<TextBox Text="{Binding Description}" Background="{x:Null}" />
获取类型对象。
text<Button Content="显示类型" Tag="{x:Type local:UserModel}" />
创建自定义标记扩展需要实现MarkupExtension
基类。
C#public class ColorExtension : MarkupExtension
{
public string ColorName { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
var colorProperty = typeof(Colors).GetProperty(ColorName);
if (colorProperty != null)
{
Color color = (Color)colorProperty.GetValue(null);
return new SolidColorBrush(color);
}
// 如果找不到颜色,返回默认黑色
return new SolidColorBrush(Colors.Black);
}
}
使用自定义标记扩展:
text<Rectangle Width="200" Height="100" Fill="{local:Color ColorName=Red}"/>
text<Window.Resources> <local:ColorConverter x:Key="MyConverter"/> <local:ViewModel x:Key="ViewModel"/> </Window.Resources> <StackPanel> <Button Content="复杂绑定示例" Height="40" Margin="10" Background="{Binding Background, Converter={StaticResource MyConverter}, Source={StaticResource ViewModel}}"/> </StackPanel>
C#public class ColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string colorName)
{
// 如果输入的颜色名是 "Red",转换为蓝色
// 否则返回白色
return colorName.ToLower() == "red"
? Brushes.Blue
: Brushes.White;
}
return Brushes.White;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
C#public class ViewModel
{
public string Background { get; set; } = "Red";
}
这里其实就是一个颜色red转换显示blue,没有啥实际意义。
text<TextBlock> <TextBlock.Text> <MultiBinding StringFormat="姓名:{0} {1}"> <Binding Path="FirstName"/> <Binding Path="LastName"/> </MultiBinding> </TextBlock.Text> </TextBlock>
C#public partial class MainWindow : Window
{
public string FirstName => "张";
public string LastName => "三";
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
}
StaticResource
而非DynamicResource
,因为性能更好标记扩展是WPF XAML中强大的特性,能够显著简化复杂的UI逻辑和数据绑定。合理使用可以提高代码的灵活性和可维护性。
本文作者:技术老小子
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!