首页 > 解决方案 > LinearGradientBrush 未按预期 WPF 工作

问题描述

解决了。见 Rekshino 的评论

我认为这应该代表桌面游戏主动追踪器的生命值。心脏只在我的电脑上按预期工作,两台不同的机器显示不同的结果。当我在另一台机器上运行程序时,无论生命值是多少,心脏都会保持红色。

这是它应该看起来的样子,以及它在我的机器上的样子:

在此处输入图像描述

<DataGridTemplateColumn>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Canvas Width="20" Height="20" HorizontalAlignment="Center" VerticalAlignment="Center">

                <Path>
                    <Path.Style>
                        <Style TargetType="Path">
                            <Style.Triggers>
                                <MultiDataTrigger>
                                    <MultiDataTrigger.Conditions>
                                        <Condition Binding="{Binding Path=IsAlive}" Value="true"/>
                                        <Condition Binding="{Binding Path=IsConscious}" Value="true"/>
                                        <Condition Binding="{Binding Path=IsStable}" Value="true"/>
                                     </MultiDataTrigger.Conditions>
                                     <MultiDataTrigger.Setters>

                                         <Setter Property="HorizontalAlignment" Value="Left"/>
                                         <Setter Property="VerticalAlignment" Value="Top"/>
                                         <Setter Property="StrokeThickness" Value="2"/>
                                         <Setter Property="Stroke" Value="Black"/>
                                         <Setter Property="Height" Value="20"/>
                                         <Setter Property="Width" Value="20"/>
                                         <Setter Property="Data" Value="M45.445,12.4445 C45.278001,4.2777179 40.097263,0.5000003 
                                                            33.5005,0.5 28.965223,0.5000003 25.020309,3.0276406 22.997637,6.7510427 L22.9725,6.8001207 
                                                            22.947363,6.7510427 C20.92469,3.0276406 16.979776,0.5000003 12.4445,0.5 5.8477349,0.5000003 
                                                            0.72517072,5.8515793 0.5,12.4445 0.278,18.944584 22.997637,37.611504 22.997637,37.611504 
                                                            22.997637,37.611504 45.611998,20.611283 45.445,12.4445 z"/>
                                         <Setter Property="Stretch" Value="Fill"/>
                                     </MultiDataTrigger.Setters>
                                 </MultiDataTrigger>
                             </Style.Triggers>
                         </Style>
                     </Path.Style>
                     <!--Heartfilling control-->
                     <Path.Fill>
                         <LinearGradientBrush StartPoint="{Binding GradientFillString}">
                             <GradientStop Color="Black"/>
                             <GradientStop Color="Red" Offset="0"/>
                         </LinearGradientBrush>
                      </Path.Fill>
                  </Path>

GradientFillString 是当前生命值与最大生命值之间的比率,格式如下:"1 " + Convert.ToString(1 - ratio)

在代码中,我省略了几个多数据触发器,它们将以不同的方式操纵画布,我认为这些方式与这个问题并不特别相关。这些将根据角色的不同状态触发。

更新。尝试 MCVE

CharacterMinimal.cs

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MCVE
{
    public class CharacterMinimal
    {
        public int MaxHealth { get; set; }
        public int CurrentHP { get; set; }
        public bool IsAlive { get; set; }

        public CharacterMinimal()
        {
            IsAlive = true;
        }
        public string GradientFillString
        {
            get
            {
                if (MaxHealth > 0)
                {
                    decimal calc = Convert.ToDecimal(CurrentHP) / Convert.ToDecimal(MaxHealth);
                    return "1 " + Convert.ToString(1 - calc);
                }
                else
                {
                    return "1 " + "1";
                }

            }
        }
    }

}

MainWindow.xaml

<Window x:Class="MCVE.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MCVE"
        mc:Ignorable="d"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="MainWindow" Height="450" Width="800">
    <Grid x:Name="Grid1">
        <DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <!--Status Image / path-->
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Canvas Width="20" Height="20" HorizontalAlignment="Center" VerticalAlignment="Center">

                                <Path>
                                    <Path.Style>
                                        <Style TargetType="Path">
                                            <Style.Triggers>
                                                <MultiDataTrigger>
                                                    <MultiDataTrigger.Conditions>
                                                        <Condition Binding="{Binding Path=IsAlive}" Value="true"/>

                                                    </MultiDataTrigger.Conditions>
                                                    <MultiDataTrigger.Setters>

                                                        <Setter Property="HorizontalAlignment" Value="Left"/>
                                                        <Setter Property="VerticalAlignment" Value="Top"/>
                                                        <Setter Property="StrokeThickness" Value="2"/>
                                                        <Setter Property="Stroke" Value="Black"/>
                                                        <Setter Property="Height" Value="20"/>
                                                        <Setter Property="Width" Value="20"/>
                                                        <Setter Property="Data" Value="M45.445,12.4445 C45.278001,4.2777179 40.097263,0.5000003 
                                                                33.5005,0.5 28.965223,0.5000003 25.020309,3.0276406 22.997637,6.7510427 L22.9725,6.8001207 
                                                                22.947363,6.7510427 C20.92469,3.0276406 16.979776,0.5000003 12.4445,0.5 5.8477349,0.5000003 
                                                                0.72517072,5.8515793 0.5,12.4445 0.278,18.944584 22.997637,37.611504 22.997637,37.611504 
                                                                22.997637,37.611504 45.611998,20.611283 45.445,12.4445 z"/>
                                                        <Setter Property="Stretch" Value="Fill"/>
                                                    </MultiDataTrigger.Setters>
                                                </MultiDataTrigger>
                                            </Style.Triggers>
                                        </Style>
                                    </Path.Style>
                                    <!--Heartfilling control-->
                                    <Path.Fill>
                                        <LinearGradientBrush StartPoint="{Binding GradientFillString}">
                                            <GradientStop Color="Black"/>
                                            <GradientStop Color="Red" Offset="0"/>
                                        </LinearGradientBrush>
                                    </Path.Fill>
                                </Path>
                            </Canvas>
                        </DataTemplate>

                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn Binding="{Binding MaxHealth}">
                </DataGridTextColumn>
            </DataGrid.Columns>

        </DataGrid>
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Collections.Generic;
using System.Windows;

namespace MCVE
{
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();
            List<CharacterMinimal> population = new List<CharacterMinimal> {
                    new CharacterMinimal(){MaxHealth = 20, CurrentHP = 10},
                    new CharacterMinimal(){MaxHealth = 30, CurrentHP = 30},
                    new CharacterMinimal(){MaxHealth = 10, CurrentHP = 2}
                };
            Grid1.DataContext = population;
        }
    }
}

标签: c#wpf

解决方案


您确实在 VewModel 中复合了一个值,LinearGradientBrush.StartPoint它的内容除其他外是一个十进制数,例如0.5. 你得到这个数字Convert.ToString(),这个数字中的小数分隔符取决于 Windows 设置,这就是为什么在某些 PC 上它不起作用的原因。

窗口设置

要解决问题,您可以使用重载Convert.ToString(decimal value, IFormatProvider provider)或仅替换,.

Convert.ToString(1 - calc).Replace(",", ".")

推荐阅读