Программно получить кисть из класса Brushes?

У меня есть свойство, которое позволяет отправлять имя строки известного цвета на мой элемент управления. Свойство принимает только известные названия цветов, например "Красный" или "Синий".

  private KnownColor _UseColor = KnownColor.Red;

    /// <summary>
    /// Gets or sets the name of the colour
    /// </summary>
    public string ColorName
    {
        get
        {
            return this._UseColor.ToString();
        }
        set
        {
            if (Enum.IsDefined(typeof(KnownColor), value))
                this._UseColour = (KnownColor)Enum.Parse(typeof(KnownColor), value);
        }
    }

И я хочу использовать это перечисление _UseColour для выбора существующей кисти из статического Класс кистей в .NET, подобный этому

Brush sysBrush = Brushes.FromKnownColor(this._UseColor);
e.Graphics.FillRectangle(sysBrush, 0, 0, 10, 10);

Вместо того, чтобы создавать новую кисть всякий раз, когда элемент управления рисуется так

using (SolidBrush brsh = new SolidBrush(Color.FromKnownColor(this._UseColor)))
    e.Graphics.FillRectangle(brsh, 0, 0, 10, 10);

Кто-нибудь знает, возможно ли это, или мне придется каждый раз создавать новую кисть?

Brushes.FromKnownColor не является методом класса Brushes


person jcharlesworthuk    schedule 28.02.2013    source источник


Ответы (4)


Почему бы не создать кисть один раз и не кэшировать ее для последующего использования?

В вашем основном классе:

private KnownColor _UseColor = KnownColor.Red;

/// <summary>
/// Gets or sets the name of the colour
/// </summary>
public string ColorName
{
    get
    {
        return this._UseColor.ToString();
    }
    set
    {
        if (Enum.IsDefined(typeof(KnownColor), value))
            this._UseColour = (KnownColor)Enum.Parse(typeof(KnownColor), value);
    }
}

private Dictionary<string, Brush> _knownBrushes = new Dictionary<string, Brush>();

public Brush ColorBrush
{
    get
    {
        if (!_knownBrushes.ContainsKey(_UseColor)) {
            _knownBrushes[_UseColor] = new SolidBrush(Color.FromKnownColor(this._UseColor));
        }

        return _knownBrushes[_UseColor];
    }
}

затем используйте его как ..

e.Graphics.FillRectangle(ColorBrush, 0, 0, 10, 10);
person Rudi Visser    schedule 28.02.2013
comment
Мне это нравится, спасибо :) вообще лучше кешировать объекты кисти, чем создавать их на лету? Разве тогда мне не нужно было бы делать мой класс одноразовым, чтобы удалить _knownBrushes в конце? - person jcharlesworthuk; 28.02.2013
comment
Вы можете заставить его размещать каждую кисть в деструкторе для вашего класса, да. - person Rudi Visser; 28.02.2013
comment
Вероятно, в _knownBrushes не будет большого количества, но я бы все же выбрал вызов TryGetValue(), а не двойной поиск в геттере. - person JRoughan; 28.02.2013

Рефлексивный подход

var properties = typeof (Brushes).GetProperties();
var property = properties.FirstOrDefault(p => p.Name == "Red");
var brush = property.GetValue(null, null); // Contains Brushes.Red

Ваш случай

Поле:

PropertyInfo[] _properties = typeof (Brushes).GetProperties();

Статический метод

static Brush GetKnownBrush(string knownColorName)
{
    var property = _properties.FirstOrDefault(p => p.Name == knownColorName);
    var brush = property.GetValue(null, null);
    return brush;
}

Применение:

var knownBrush = GetKnownBrush(ColorName);

Свойство экземпляра

Brush KnownBrush
{
    get
    {
        var property = _properties.FirstOrDefault(p => p.Name == ColorName);
        var brush = property.GetValue(null, null);
        return brush;
    }
}

Применение:

var knownBrush = KnownBrush;

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

person Ryszard Dżegan    schedule 28.02.2013

Если вам нужно решение, которое может искать кисть по цвету, даже если цвет может не иметь известного имени, вы можете создать словарь, который использует цвет:

void Main()
{
    var brush = KnownBrush(Color.FromArgb(255, 0, 0));
    brush.Dump();
}

private static Dictionary<Tuple<byte, byte, byte, byte>, SolidBrush> _KnownBrushes;
public static SolidBrush KnownBrush(Color color)
{
    if (_KnownBrushes == null)
    {
        _KnownBrushes = new Dictionary<Tuple<byte, byte, byte, byte>, SolidBrush>();
        foreach (var propertyInfo in typeof(Brushes).GetProperties())
        {
            if (propertyInfo.PropertyType == typeof(Brush))
            {
                var brush = propertyInfo.GetValue(null) as SolidBrush; // not a typo
                if (brush != null)
                    _KnownBrushes[Tuple.Create(brush.Color.R, brush.Color.G, brush.Color.B, brush.Color.A)] = brush;
            }
        }
    }

    SolidBrush result;
    _KnownBrushes.TryGetValue(Tuple.Create(color.R, color.G, color.B, color.A), out result);
    return result;
}
person Lasse V. Karlsen    schedule 28.02.2013

Остальные ответы сложны. Вот однострочник для преобразования строки «фиолетовый» в кисть сплошного цвета:

new SolidColorBrush((Color)ColorConverter.ConvertFromString("purple"))

Вспоминая using System.Windows.Media;

person Colonel Panic    schedule 28.02.2013