Страницы

Поиск по вопросам

понедельник, 11 февраля 2019 г.

WPF создание ресурса с несколькими параметрами

У меня на окне располагается 9 StackPanel, я делаю для них анимацию смены цвета при наведении мыши

У каждой панели разный цвет и соответственно менять тоже нужно разный цвет, а писать 9 раз этот код для каждой панели, ну понимаете... Можно ли как то создать ресурс с параметрами (входным и выходным цветом)?


Ответ

Можно, но неочевидным образом.
К сожалению, в анимации невозможно использовать не Binding, не DynamicResource, поэтому придётся пойти обходным путём.
Идея такова: будем вместо цвета анимировать число от 0.0 до 1.0 и обратно, а цвет фона вычислим из начального и конечного цветов через конвертер.
Реализуем!
Итак, для начала конвертер, который будет интерполировать цвета. Он очень простой. Идея одолжена здесь
class ColorInterpolationConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object p, CultureInfo ci) { if (values.Contains(DependencyProperty.UnsetValue)) return Binding.DoNothing; Color from = (Color)values[0]; Color to = (Color)values[1]; double ratio = (double)values[2]; return from + (to - from) * (float)ratio; }
public object[] ConvertBack(object value, Type[] targetTypes, object p, CultureInfo ci) { throw new NotImplementedException(); } }
Теперь, нам нужно задать начальный и конечный цвет. Это должны быть, по идее, attached property. Так же нам нужно attached property для текущего значения соотношения между начальным и конечным цветами, которое мы будем анимировать. Определяем их во вспомогательном классе:
static class ColorExtensions { #region attached property double Ratio public static double GetRatio(DependencyObject obj) => (double)obj.GetValue(RatioProperty);
public static void SetRatio(DependencyObject obj, double value) => obj.SetValue(RatioProperty, value);
public static readonly DependencyProperty RatioProperty = DependencyProperty.RegisterAttached( "Ratio", typeof(double), typeof(ColorExtensions)); #endregion
#region attached property Color BaseColor public static Color GetBaseColor(DependencyObject obj) => (Color)obj.GetValue(BaseColorProperty);
public static void SetBaseColor(DependencyObject obj, Color value) => obj.SetValue(BaseColorProperty, value);
public static readonly DependencyProperty BaseColorProperty = DependencyProperty.RegisterAttached( "BaseColor", typeof(Color), typeof(ColorExtensions)); #endregion
#region attached property Color HoverColor public static Color GetHoverColor(DependencyObject obj) => (Color)obj.GetValue(HoverColorProperty);
public static void SetHoverColor(DependencyObject obj, Color value) => obj.SetValue(HoverColorProperty, value);
public static readonly DependencyProperty HoverColorProperty = DependencyProperty.RegisterAttached( "HoverColor", typeof(Color), typeof(ColorExtensions)); #endregion }
Окей, теперь сам стиль.

Используем:

Результат:

Кода получилось довольно много, но в принципе, его можно повторно использовать. Если бы в анимации можно было бы задавать параметры более гибко, такая сложность бы не понадобилась.

Комментариев нет:

Отправить комментарий