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

问题描述

我有一个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,CultureInfo culture)
    {
        return _value; //Todo: Will this work?
    }
}

public sealed class RaceMapColorConverter : StringToBrushConverter
{
    public RaceMapColorConverter() : base("",new Color { R = 255,G = 0,B = 0 },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,以防万一它有任何技巧可以帮助您。任何帮助将不胜感激。

解决方法

作为一般的经验法则,当数据转换需要双向时(即,视图模型可以再次查看和返回),应使用转换器,而仅单向时应使用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,CultureInfo culture)
    {
        return new object[] { Binding.DoNothing,Binding.DoNothing };
    }
}

然后在您的应用程序中,将两个绑定都传递到这种类型的MultiBinding中,并在比较结果为true时使用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>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...