Как преобразовать цвет в кисть в XAML?

Я хочу преобразовать значение System.Windows.Media.Color в System.Windows.Media.Brush. Значение цвета привязано к свойству Fill объекта Rectangle. Свойство Fill принимает объект Brush, поэтому мне нужен объект IValueConverter для выполнения преобразования.

Есть ли в WPF встроенный конвертер или мне нужно создать свой? Как я могу создать свой собственный, если в этом возникнет необходимость?


person dthrasher    schedule 22.07.2010    source источник
comment
Возможный дубликат: stackoverflow .com / questions / 372693 /.   -  person Jakob Christensen    schedule 22.07.2010
comment
Не думаю, что это дубликат. Я хочу преобразовать из объекта Color, а не из строкового значения, такого как Red. И я хотел бы реализовать его как конвертер XAML, а не выполнять преобразование в коде C # позади.   -  person dthrasher    schedule 22.07.2010


Ответы (7)


Похоже, придется создавать свой конвертер. Вот простой пример для начала:

public class ColorToSolidColorBrushValueConverter : IValueConverter {

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        if (null == value) {
            return null;
        }
        // For a more sophisticated converter, check also the targetType and react accordingly..
        if (value is Color) {
            Color color = (Color)value;
            return new SolidColorBrush(color);
        }
        // You can support here more source types if you wish
        // For the example I throw an exception

        Type type = value.GetType();
        throw new InvalidOperationException("Unsupported type ["+type.Name+"]");            
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        // If necessary, here you can convert back. Check if which brush it is (if its one),
        // get its Color-value and return it.

        throw new NotImplementedException();
    }
}

Чтобы использовать его, объявите его в разделе ресурсов.

<local:ColorToSolidColorBrushValueConverter  x:Key="ColorToSolidColorBrush_ValueConverter"/>

И использовать его в привязке как статический ресурс:

Fill="{Binding Path=xyz,Converter={StaticResource ColorToSolidColorBrush_ValueConverter}}"

Я не тестировал. Сделайте комментарий, если он не работает.

person HCL    schedule 22.07.2010
comment
Большое спасибо @Chris Valentine. Несмотря на то, что ответ Йенса очень элегантен, в моем случае я не смог его использовать, и мне пришлось использовать конвертер. Или, возможно, я не мог понять, как реализовать SolidColorBrush в моем случае. - person philologon; 24.05.2014

Я знаю, что очень опаздываю на вечеринку, но для этого вам не нужен конвертер.

Ты мог бы сделать

<Rectangle>
    <Rectangle.Fill>
        <SolidColorBrush Color="{Binding YourColorProperty}" />
    </Rectangle.Fill>
</Rectangle>
person Jens    schedule 15.03.2011
comment
Это решение намного лучше, чем принятый ответ. Спасибо! - person Antoine Aubry; 02.11.2012
comment
Хотя мне нравится это решение, оно действительно приводит к раздражающим предупреждениям, как описано здесь: stackoverflow.com/questions/7926204/ - person l33t; 22.05.2014
comment
Если вы не понимаете, что такое YourColorProperty, как я, скорее всего, это свойство, которое можно просмотреть из текущей области XAML в вашем коде программной части C #. - person Nathaniel Ruiz; 16.01.2019

Converter здесь не нужен. Вы можете определить Brush в XAML и использовать его. Было бы лучше определить Brush как Resource, чтобы его можно было использовать в других требуемых местах.

XAML выглядит следующим образом:

<Window.Resources>
    <SolidColorBrush Color="{Binding ColorProperty}" x:Key="ColorBrush" />
</Window.Resources>
<Rectangle Width="200" Height="200" Fill="{StaticResource ColorBrush}" />
person Kylo Ren    schedule 30.01.2016

Я хотел сделать этот путь HCL, а не путь Йенса, потому что у меня есть много вещей, привязанных к Color, поэтому меньше дублирования и шаблонных узлов .Fill.

Однако при попытке написать его ReSharper указал мне на реализацию ColorToSolidColorBrushConverter в WPF Toolkit. Вам необходимо включить следующее объявление пространства имен в главный узел Window / UserControl:

xmlns:Toolkit="clr-namespace:Microsoft.Windows.Controls.Core.Converters;assembly=WPFToolkit.Extended"

Затем статический ресурс в ресурсах Window / UserControl:

<Toolkit:ColorToSolidColorBrushConverter x:Key="colorToSolidColorBrushConverter" />

Тогда вы можете сделать это, как ответ HCL:

<Rectangle Fill="{Binding Color, Converter={StaticResource colorToSolidColorBrushConverter}}" />
person Jackson Pope    schedule 19.07.2012

С еще одним улучшением ответа HCL я протестировал его - он работает.

public class ColorToSolidColorBrushValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null)
            return null;

        if (value is Color)
            return new SolidColorBrush((Color)value);

        throw new InvalidOperationException("Unsupported type [" + value.GetType().Name + "], ColorToSolidColorBrushValueConverter.Convert()");
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null)
            return null;

        if (value is SolidColorBrush)
            return ((SolidColorBrush)value).Color;

        throw new InvalidOperationException("Unsupported type [" + value.GetType().Name + "], ColorToSolidColorBrushValueConverter.ConvertBack()");
    }

}
person G.Y    schedule 24.02.2013
comment
После публикации ... Я заметил ответ Йенса ... который точен :) - person G.Y; 24.02.2013

Конвертер:

[ValueConversion(typeof(SolidColorBrush), typeof(Color))]
public class SolidBrushToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(value is SolidColorBrush)) return null;
        var result = (SolidColorBrush)value;
        return result.Color;
    }

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

XAML:

//...
<converters:SolidBrushToColorConverter x:Key="SolidToColorConverter" />
//...
<Color>
    <Binding Source="{StaticResource YourSolidColorBrush}"
             Converter="{StaticResource SolidToColorConverter}">
    </Binding>
</Color>
//...
person Stacked    schedule 24.10.2014

В дополнение к ответу HCL: если вы не хотите заботиться о том, используется ли System.Windows.Media.Color или System.Drawing.Color, вы можете использовать этот конвертер, который принимает оба:

public class ColorToSolidColorBrushValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        switch (value)
        {
            case null:
                return null;
            case System.Windows.Media.Color color:
                return new SolidColorBrush(color);
            case System.Drawing.Color sdColor:
                return new SolidColorBrush(System.Windows.Media.Color.FromArgb(sdColor.A, sdColor.R, sdColor.G, sdColor.B));
        }

        Type type = value.GetType();
        throw new InvalidOperationException("Unsupported type [" + type.Name + "]");
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
} 
person Norman    schedule 29.03.2018