C# WPF 标签背景根据百分比属性填充

C# WPF Label background filled according to a percentage property

提问人:DarkWarrior 提问时间:11/7/2023 更新时间:11/7/2023 访问量:28

问:

我想做一个 ,它可以有一个名为 Percentage 的属性,背景将根据该百分比填充。示例:然后背景颜色将仅填充标签大小的 70%。CustomControl Labellabel.Percentage = 70

example

我创建了一个:Custom Control

<UserControl x:Class="NameSpace.PercentageLabel"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:NameSpace"                
          Background="Transparent">


<Border x:Name="backgroundBorder" Background="Transparent">
    <TextBlock x:Name="textBlock" Text="Label Text" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White"/>
</Border>

我像这样设置 PercentageLabel 的属性:

 public partial class PercentageLabel : UserControl
 {

     public PercentageLabel()
     {
         InitializeComponent();
     }

     public static readonly DependencyProperty PercentageProperty =
       DependencyProperty.Register("Percentage", typeof(double), typeof(PercentageLabel), new PropertyMetadata(0.0, OnPercentageChanged));

     public double Percentage
     {
         get { return (double)GetValue(PercentageProperty); }
         set { SetValue(PercentageProperty, value); }
     }

     public static readonly DependencyProperty FillColorProperty =
         DependencyProperty.Register("FillColor", typeof(Brush), typeof(PercentageLabel), new PropertyMetadata(Brushes.Black));

 

     public Brush FillColor
     {
         get { return (Brush)GetValue(FillColorProperty); }
         set { SetValue(FillColorProperty, value); }
     }

     private static void OnPercentageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
     {
         var label = (PercentageLabel)d;
         var newPercentage = (double)e.NewValue;

         // Ensure the percentage is within the valid range
         newPercentage = Math.Min(100, Math.Max(0, newPercentage));

         // Calculate the width of the filled and unfilled parts of the background
         var fillWidth = label.ActualWidth * (newPercentage / 100);          

         // Update the background color (FillColor) and the filled background width
         label.backgroundBorder.Background = label.FillColor;
         label.backgroundBorder.Width = fillWidth;
         label.backgroundBorder.HorizontalAlignment= HorizontalAlignment.Left;
     }
 }   

最后,我在 Window 中添加了自定义控件。

<local:PercentageLabel Grid.Row="0" Grid.Column="0" Percentage="70" FillColor="Green"/>

问题:

  • 我无法编辑自定义标签内容,否则背景会消失。
  • 标签文本也采用百分比的大小,因此我们看不到任何低百分比值的文本。
C# 标签 WPF 控件 背景色

评论


答:

1赞 Alander 11/7/2023 #1

您可以使用网格和重叠的控件,textBlockBar 是您的百分比条,可以填充您需要的任何内容

textBlockBG 是包含文本和背景的背景框Sample

在用户控件中:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="50"></RowDefinition>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"></ColumnDefinition>
    </Grid.ColumnDefinitions>
    
    <Border x:Name="backgroundBorder1" Background="Transparent" Grid.Row="0" Grid.Column="0">
        <TextBlock x:Name="textBlockBar"  HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" Opacity="0.1" Text="">
        </TextBlock>
    </Border>
    <Border x:Name="backgroundBorder2" Background="Transparent" Grid.Row="0" Grid.Column="0">
        <TextBlock x:Name="textBlockBG"  HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" Opacity="1" Text="">
        </TextBlock>
    </Border>
</Grid>

相应地更新 Usercontrol 类:

public partial class PercentageLabel : UserControl
{

    public PercentageLabel()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty PercentageProperty =
      DependencyProperty.Register("Percentage", typeof(double), typeof(PercentageLabel), new PropertyMetadata(0.0, OnPercentageChanged));

    public double Percentage
    {
        get { return (double)GetValue(PercentageProperty); }
        set { SetValue(PercentageProperty, value); }
    }

    public static readonly DependencyProperty FillColorProperty =
        DependencyProperty.Register("FillColor", typeof(Brush), typeof(PercentageLabel), new PropertyMetadata(Brushes.Black));

    public string Text
    {
        get
        {
            return this.textBlockBG.Text;
        }
        set
        {
            this.textBlockBG.Text = value;
        }
    }

    public Brush FillColor
    {
        get { return (Brush)GetValue(FillColorProperty); }
        set { SetValue(FillColorProperty, value); }
    }

    public Brush BackColor
    {
        get { return this.Background; }
        set { this.Background = value; }
    }

    public Brush TextColor
    {
        get { return this.textBlockBG.Foreground; }
        set { this.textBlockBG.Foreground = value; }
    }

    private static void OnPercentageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var label = (PercentageLabel)d;
        var newPercentage = (double)e.NewValue;

        // Ensure the percentage is within the valid range
        newPercentage = Math.Min(100, Math.Max(0, newPercentage));

        // Calculate the width of the filled and unfilled parts of the background
        var fillWidth = label.ActualWidth * (newPercentage / 100);

        // Update the background color (FillColor) and the filled background width
        label.backgroundBorder1.Background = label.FillColor;
        label.backgroundBorder1.Width = fillWidth;
        label.backgroundBorder1.HorizontalAlignment = HorizontalAlignment.Left;

        
    }

然后在你的窗口中,只需这样做

<local:PercentageLabel x:Name="pLabel1" Grid.Row="0" Grid.Column="0" Percentage="70" FillColor="Blue" BackColor="Orange" TextColor="Yellow"/>

虽然有一个问题,但您需要在调整窗口大小时处理 % 不遵循窗口大小,我会留给您:)修复它