Страницы

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

понедельник, 6 января 2020 г.

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

#wpf #xaml


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


    



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


Ответы

Ответ 1



Можно, но неочевидным образом. К сожалению, в анимации невозможно использовать ни 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 } Окей, теперь сам стиль. Используем: Результат: Кода получилось довольно много, но в принципе, его можно повторно использовать. Если бы в анимации можно было бы задавать параметры более гибко, такая сложность бы не понадобилась.

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

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