如果内容与另一个属性值匹配,则更改标签前景

Posted

技术标签:

【中文标题】如果内容与另一个属性值匹配,则更改标签前景【英文标题】:Change Label Foreground if content matches another property value 【发布时间】:2021-01-03 17:52:36 【问题描述】:

我有一个 DataGrid 显示带有一些详细信息的地图列表。我正在尝试更改当前处于活动状态的地图的前景色,但我正在努力。我编写了以下转换器来检查 DataGrid 项的值是否与当前地图的名称匹配,但我不确定如何从 XAML 传递当前地图的名称。

转换器:

public class StringToBrushConverter : IValueConverter

    public string CurrentMapName  get; set; 
    public Color CurrentMapColor  get; set; 
    public Color OtherMapColor  get; set; 

    string _value = "";

    public StringToBrushConverter(string currentMapName, Color currentMapColor, Color otherMapColor)
    
        CurrentMapName = currentMapName;
        CurrentMapColor = currentMapColor;
        OtherMapColor = otherMapColor;
    

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    
        _value = value as string;
        return (string)value == CurrentMapName ? new SolidColorBrush(CurrentMapColor) : new SolidColorBrush(OtherMapColor);
    

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    
        return _value; //TODO: Will this work?
    


public sealed class RaceMapColorConverter : StringToBrushConverter

    public RaceMapColorConverter() : base("", new Color  R = 255, G = 0, B = 0 , new Color  R = 255, G = 255, B = 255 )  

XAML:

<DataGrid x:Name="MapHistory"
        AutoGenerateColumns="False"
        IsReadOnly="True"
        HeadersVisibility="Column"
        GridLinesVisibility="None"
        CanUserSortColumns="False"
        Style="StaticResource MapTimerDataGrid"
        CellStyle="StaticResource MapTimerControlCell"
        ItemsSource="Binding Plan.Plan">
    <DataGrid.Resources>
<!-- The Binding in CurrentMapName is not valid. It says it can only be set on a dependency property but I'm not sure how to do that -->
        <conv:RaceMapColorConverter x:Key="MapColorConverter" CurrentMapName="Binding CurrentMap.MapName" CurrentMapColor="Red" OtherMapColor="White" />
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Map" Width="*">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Label Content="Binding Map.MapName" Foreground="Binding Map.MapName, Converter=StaticResource MapColorConverter" Padding="0" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <!-- Other columns removed to shorten -->
    </DataGrid.Columns>
</DataGrid>

我也不确定如何实现“ConvertBack()”。将原始值存储在转换器中是否有效?或者可以为同一个控件创建一个新实例?我是否以正确的方式去做这件事?认为还值得一提的是,我正在使用 Caliburn.Micro,以防万一它有任何可能有用的技巧。任何帮助将不胜感激。

【问题讨论】:

这里真的需要ConvertBack,从画笔转换为地图名称吗? remarks section of ConvertBack 方法告诉在这种情况下使用 DependencyProperty.UnsetValueBinding.DoNothing 【参考方案1】:

作为一般经验法则,当数据转换需要双向(即视图模型以查看并再次返回)时,您应该使用转换器,而当它只是单向时,您应该使用 DataTriggers。这回答了您关于 ConvertBack 的问题(在您提供的示例中,无论如何都不会调用它,在这种情况下您可以只返回 Binding.DoNothing)。

但是,在这种特殊情况下,需要使用转换器,因为您需要比较两个绑定。我不会为这个非常具体的任务编写应用程序感知转换器,而是选择更通用的 MultiConverter,它只比较您提供的两个值:

public class EqualityConverter : IMultiValueConverter

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    
        return (values.Length==2) && Object.Equals(values[0], values[1]);
    

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    
        return new object[]  Binding.DoNothing, Binding.DoNothing ;
    

然后回到您的应用程序中,您将两个绑定都传递到这种类型的 MultiBinding 中,并在比较结果为真时使用 DataTrigger 更改地图颜色:

<Label Content="Binding Map.MapName">
    <Label.Style>
        <Style TargetType="x:Type TextBlock" BasedOn="StaticResource x:Type Label">
            <Setter Property="Foreground" Value="Red" /> <!-- normal map color -->
            <Style.Triggers>
                <DataTrigger Value="True">
                    <DataTrigger.Binding>
                        <MultiBinding Converter="StaticResource EqualityConverter" Mode="OneWay">
                            <Binding Path="Map.MapName" />
                            <Binding Path="CurrentMapName" />
                        </MultiBinding>
                    </DataTrigger.Binding>
                    <Setter Property="Foreground" Value="White" /> <!-- other map color -->
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Label.Style>
</Label>

【讨论】:

以上是关于如果内容与另一个属性值匹配,则更改标签前景的主要内容,如果未能解决你的问题,请参考以下文章

按属性将对象数组与另一个对象的键进行比较

将一个数组值与另一个多维数组匹配,然后从多维数组中获取值

如果发现一个逗号分隔记录与另一个逗号分隔记录匹配,则获取记录

更改文本框的值,与另一个具有比率的文本框值相比

ms sql server字符串与另一个具有多个值的字符串进行比较

如果属性值= [重复],则jquery更改类