如何为WPF UserControl实例传递变量,实现可复用AreaTile控件?
实现可配置的WPF AreaTile UserControl
你完全可以创建这样的UserControl来避免重复代码,下面提供两种方案:一种是符合WPF规范的极简依赖属性方案(推荐),另一种是纯XAML方案(适合不想写C#的场景)。
方案1:极简依赖属性+XAML绑定(推荐)
这是WPF中自定义可配置控件的标准做法,代码量极少且语义清晰。
1. 创建AreaTile.xaml
<UserControl x:Class="YourAppNamespace.AreaTile" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="2*"/> <RowDefinition Height="1*"/> <RowDefinition Height="1*"/> </Grid.RowDefinitions> <!-- 顶部标题区域 --> <Rectangle Grid.Row="0" Grid.ColumnSpan="2" Fill="{Binding TileColour, RelativeSource={RelativeSource AncestorType=UserControl}}" RadiusX="20" RadiusY="20" Margin="5"/> <TextBlock Grid.Row="0" Grid.ColumnSpan="2" Text="{Binding Title, RelativeSource={RelativeSource AncestorType=UserControl}}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{StaticResource textColour1}" FontSize="16" FontWeight="Medium"/> <!-- 左侧TARGET区域 --> <Rectangle Grid.Row="1" Grid.Column="0" Grid.RowSpan="2" Fill="{Binding TileColour, RelativeSource={RelativeSource AncestorType=UserControl}}" RadiusX="25" RadiusY="25" Margin="5,0,5,0"/> <TextBlock Grid.Row="1" Grid.Column="0" Text="TARGET" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{StaticResource textColour1}"/> <TextBlock Grid.Row="2" Grid.Column="0" Text="0" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{StaticResource textColour1}"/> <!-- 右侧ACTUAL区域 --> <Rectangle Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Fill="{Binding TileColour, RelativeSource={RelativeSource AncestorType=UserControl}}" RadiusX="25" RadiusY="25" Margin="5,0,5,0"/> <TextBlock Grid.Row="1" Grid.Column="1" Text="ACTUAL" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{StaticResource textColour1}"/> <TextBlock Grid.Row="2" Grid.Column="1" Text="0" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{StaticResource textColour1}"/> </Grid> </UserControl>
2. 添加AreaTile.xaml.cs的依赖属性
using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace YourAppNamespace { public partial class AreaTile : UserControl { // 标题依赖属性,默认值为"TITLE" public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(nameof(Title), typeof(string), typeof(AreaTile), new PropertyMetadata("TITLE")); // 填充颜色依赖属性 public static readonly DependencyProperty TileColourProperty = DependencyProperty.Register(nameof(TileColour), typeof(Brush), typeof(AreaTile)); public string Title { get => (string)GetValue(TitleProperty); set => SetValue(TitleProperty, value); } public Brush TileColour { get => (Brush)GetValue(TileColourProperty); set => SetValue(TileColourProperty, value); } public AreaTile() => InitializeComponent(); } }
3. 在MainWindow.xaml中调用
<Window x:Class="YourAppNamespace.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:YourAppNamespace" Title="MainWindow" Height="450" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <local:AreaTile Grid.Row="0" Grid.Column="0" Title="FirstTitle" TileColour="{StaticResource colour1}"/> <local:AreaTile Grid.Row="0" Grid.Column="1" Title="SecondTitle" TileColour="{StaticResource colour2}"/> <local:AreaTile Grid.Row="0" Grid.Column="2" Title="ThirdTitle" TileColour="{StaticResource colour3}"/> <!-- 重复上述代码即可快速创建剩下的6个Tile --> </Grid> </Window>
方案2:纯XAML实现(无需C#代码)
如果完全不想编写C#代码,可以复用UserControl的现有属性(如Tag、Foreground)来传递值,但这种方式语义性较弱,仅适合简单场景:
AreaTile.xaml(纯XAML)
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid> <!-- 结构与方案1一致,仅绑定方式修改 --> <Rectangle Grid.Row="0" Grid.ColumnSpan="2" Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=UserControl}}" RadiusX="20" RadiusY="20" Margin="5"/> <TextBlock Grid.Row="0" Grid.ColumnSpan="2" Text="{Binding Tag, RelativeSource={RelativeSource AncestorType=UserControl}}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{StaticResource textColour1}" FontSize="16" FontWeight="Medium"/> <!-- 其余矩形Fill绑定到Foreground,文本保持固定 --> <Rectangle Grid.Row="1" Grid.Column="0" Grid.RowSpan="2" Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=UserControl}}" RadiusX="25" RadiusY="25" Margin="5,0,5,0"/> <Rectangle Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=UserControl}}" RadiusX="25" RadiusY="25" Margin="5,0,5,0"/> <!-- 剩余TextBlock结构与方案1一致 --> </Grid> </UserControl>
MainWindow中调用
<local:AreaTile Grid.Row="0" Grid.Column="0" Tag="FirstTitle" Foreground="{StaticResource colour1}"/>
注意:纯XAML方案仅适合少数属性需要配置的场景,若后续需要扩展更多可配置项(如TARGET/ACTUAL的文本、底部数值),依赖属性方案会更易于维护。
内容的提问来源于stack exchange,提问作者FuzzUK
相关产品推荐
相关产品推荐

