在IValueConverter中使用FindResource

3
我有一个值转换器,可以将数字转换为画刷颜色。我需要做的是将return Brushes.Red;这一行改为return (Brush)FindResource("PrimaryHueMidBrush");,这样我就可以返回主题的颜色了。问题在于我不知道如何声明(Brush)FindResource("PrimaryHueMidBrush");。欢迎任何帮助。谢谢您提前的帮助。
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    double.TryParse(value.ToString(), out double val);

    if (val == 1)
    {
        return Brushes.Red;
    }
    else if(val == 0.5)
    {
        return Brushes.MediumVioletRed;
    }
    else if(val==0)
    {
        return Brushes.Transparent;
    }
    else
    {
        return Brushes.Transparent;
    }
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
    throw new NotImplementedException();
}
2个回答

7

不要在转换器中调用FindResource,最好为动态Brushes添加一个或多个属性:

public class YourConverter : IValueConverter
{
    public Brush FirstBrush { get; set; }
    public Brush SecondBrush { get; set; }

    public object Convert(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        double val = (double)value;

        if (val >= 1)
        {
            return FirstBrush;
        }

        if (val >= 0.5)
        {
            return SecondBrush;
        }

        return Brushes.Transparent;
    }

    public object ConvertBack(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

您可以在应用程序或窗口的资源中声明它,如下所示:

您可以在应用程序或窗口的资源中声明它,如下所示:

<local:YourConverter x:Key="YourConverter"
    FirstBrush="{StaticResource PrimaryHueMidBrush}"
    SecondBrush="MediumVioletRed"/>

非常感谢,它解决了我的问题。你是我的英雄:D - Erjon
抱歉,这是我第一次在这里:D。 - Erjon
太棒了!我自己从来没有想到过这个。 - RubberDuck

0
要访问FindResource,您需要一个FrameworkElement,因此最好的方法可能是使用MultiValueConverter,并将使用转换器的元素作为第二个值传递。
转换器:
public class WhateverThisIsCalledConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        // Insert type- and sanity-checks here
        double val = (double)values[0];
        FrameworkElement callingElement = (FrameworkElement)values[1];

        if (val >= 1)
        {
            return callingElement.FindResource("PrimaryHueMidBrush");
        }
        if (val >= 0.5)
        {
            return Brushes.MediumVioletRed;
        }

        return Brushes.Transparent;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return Enumerable.Repeat(DependencyProperty.UnsetValue, targetTypes.Length).ToArray();
    }
}

XAML中的使用方法:

<Window.Resources>
    <local:WhateverThisIsCalledConverter x:Key="Converter"/>
    <SolidColorBrush Color="Red" x:Key="PrimaryHueMidBrush"/>
</Window.Resources>
<Grid>
    <Grid.Background>
        <MultiBinding Converter="{StaticResource Converter}">
            <Binding Path="Value"/>
            <Binding RelativeSource="{RelativeSource Self}"/>
        </MultiBinding>
    </Grid.Background>
</Grid>

关于您当前的实现,有几点需要注意:

  • 尽量避免在双精度浮点数上使用==,它们不是无限精确的。
  • 当您在if之前return时,不需要所有这些else
  • ConvertBack方法应该被实现(可以自由选择其他异常,Binding.DoNothingDependencyProperty.UnsetValue)。
  • 如果您知道您的值是一个双精度浮点数,那么只需将其强制转换即可。

关于最后一条注释,你应该在代码示例中展示它。你还需要检查values[1] as FrameworkElement的结果是否为null,或者更好的直接进行类型转换。 - Clemens
@Clemens 是的,这段代码并不是百分之百可靠的,因为我不得不做出很多假设 - 它也没有包含任何合理性检查。 - Manfred Radlwimmer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接