web-dev-qa-db-fra.com

Comment convertir une couleur en pinceau en XAML?

Je souhaite convertir une valeur System.Windows.Media.Color en System.Windows.Media.Brush. La valeur de la couleur est liée à la propriété Fill d'un objet Rectangle. La propriété Fill prend un objet Brush, j'ai donc besoin d'un objet IValueConverter pour effectuer la conversion.

Existe-t-il un convertisseur intégré dans WPF ou dois-je créer le mien? Comment puis-je créer le mien si cela devient nécessaire?

48
dthrasher

Il semble que vous deviez créer votre propre convertisseur. Voici un exemple simple pour commencer:

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();
    }
}

Pour l'utiliser, déclarez-le dans la section ressource.

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

Et l'utiliser dans la liaison comme une ressource statique:

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

Je ne l'ai pas testé. Faites un commentaire si cela ne fonctionne pas.

62
HCL

Je sais que je suis vraiment en retard à la fête, mais vous n'avez pas besoin d'un convertisseur pour cela.

Vous pourriez faire

<Rectangle>
    <Rectangle.Fill>
        <SolidColorBrush Color="{Binding YourColorProperty}" />
    </Rectangle.Fill>
</Rectangle>
130
Jens

Je voulais faire ce chemin de HCL plutôt que celui de Jens parce que j'ai beaucoup de choses liées au Color, donc il y a moins de duplication et de plaque chauffante .Fill nœuds.

Cependant, en essayant de l'écrire, ReSharper m'a pointé vers l'implémentation WPF Toolkit du ColorToSolidColorBrushConverter. Vous devez inclure la déclaration d'espace de noms suivante dans le nœud principal Window/UserControl:

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

Puis une ressource statique dans les ressources Window/UserControl:

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

Ensuite, vous pouvez le faire comme la réponse de HCL:

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

Un Converter n'est pas nécessaire ici. Vous pouvez définir un Brush dans XAML et l'utiliser. Il serait préférable de définir le Brush comme un Resource afin qu'il puisse être utilisé à d'autres endroits requis.

XAML est comme ci-dessous:

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

Avec une amélioration supplémentaire de la réponse HCL, je l'ai testée - cela fonctionne.

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()");
    }

}
3
G.Y

En plus de la réponse HCL: si vous ne voulez pas vous soucier si System.Windows.Media.Color est utilisé ou System.Drawing.Color, vous pouvez utiliser ce convertisseur, qui accepte les deux:

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();
    }
} 
1
Norman

Convertisseur:

[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>
//...
1
Stacked