Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
18 / 5 / 2
Регистрация: 01.12.2020
Сообщений: 6
1
WPF

TemplateBinding Content x2

01.12.2020, 10:14. Показов 1785. Ответов 4

Author24 — интернет-сервис помощи студентам
Мне нужно менять цвет контента кнопки при наведение на кнопку курсора мыши, но т.к. ColorAnimation не может работать с DynamicResource, он мне не подходит. Поэтому я подумал решить эту проблему так: рисовать контент дважды(друг на друге),
назначив нужные цвета, а затем манипулировать прозрачностью:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<Style
        TargetType="Button"
        BasedOn="{StaticResource MaterialDesignToolButton}"
        x:Key="TitleBarButton">
        <Setter Property="Width" Value="20" />
        <Setter Property="Height" Value="20" />
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="BorderBrush" Value="Transparent" />
        <Setter Property="Padding" Value="0" />
        <Setter Property="Foreground" Value="{DynamicResource PrimaryHueDarkForegroundBrush}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate
                    TargetType="Button">
                    <materialDesign:Ripple
                        ContentTemplate="{TemplateBinding ContentTemplate}"
                        Focusable="False"
                        ContentStringFormat="{TemplateBinding ContentStringFormat}"
                        HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                        VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                        Padding="{TemplateBinding Padding}"
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
                        <Grid>
                            <UserControl
                                SnapsToDevicePixels="False"
                                x:Name="OnMouseContent"
                                Foreground="{DynamicResource PrimaryHueMidBrush}"
                                Opacity="0"
                                Content="{TemplateBinding Content}" />
                            <UserControl
                                SnapsToDevicePixels="False"
                                x:Name="DefaultContent"
                                Foreground="{TemplateBinding Foreground}"
                                Opacity="1"
                                Content="{TemplateBinding Content}" />
                        </Grid>
                    </materialDesign:Ripple>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Trigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation
                                            Storyboard.TargetName="OnMouseContent"
                                            Storyboard.TargetProperty="Opacity"
                                            To="1.0"
                                            Duration="0:0:0:0.2" />
                                        <DoubleAnimation
                                            Storyboard.TargetName="DefaultContent"
                                            Storyboard.TargetProperty="Opacity"
                                            To="0.0"
                                            Duration="0:0:0:0.2" />
                                    </Storyboard>
                                </BeginStoryboard>
                            </Trigger.EnterActions>
                            <Trigger.ExitActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation
                                            Storyboard.TargetName="OnMouseContent"
                                            Storyboard.TargetProperty="Opacity"
                                            To="0.0"
                                            Duration="0:0:0:0.2" />
                                        <DoubleAnimation
                                            Storyboard.TargetName="DefaultContent"
                                            Storyboard.TargetProperty="Opacity"
                                            To="1.0"
                                            Duration="0:0:0:0.2" />
                                    </Storyboard>
                                </BeginStoryboard>
                            </Trigger.ExitActions>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Opacity" Value="0.23" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
Теперь, когда я навожу мышь на кнопку, элемент "DefaultContent" становится прозрачным, но элемент "OnMouseContent" не становится непрозрачным.

Проблема в этом куске кода:
XML
1
2
3
4
5
6
7
8
9
10
11
12
<UserControl
        SnapsToDevicePixels="False"
        x:Name="OnMouseContent"
        Foreground="{DynamicResource PrimaryHueMidBrush}"
        Opacity="0"
        Content="{TemplateBinding Content}" />
<UserControl
        SnapsToDevicePixels="False"
        x:Name="DefaultContent"
        Foreground="{TemplateBinding Foreground}"
        Opacity="1"
        Content="{TemplateBinding Content}" />
В Live Visual Tree видно, что контент привязался только к последнему UserControl. Cобственно, почему и как это можно исправить?
Название: Screenshot_2.png
Просмотров: 59

Размер: 4.1 Кб
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.12.2020, 10:14
Ответы с готовыми решениями:

TemplateBinding
&lt;Style x:Key=&quot;RoundButton&quot; TargetType=&quot;Button&quot;&gt; &lt;Setter Property=&quot;Template&quot;&gt; ...

Не удается сделать TemplateBinding в сеттере триггера на Value для любого свойства
Доброго времени суток, возникла следующая проблема: Требуется написать ControlTemplate на...

Не корректное функционирование TemplateBinding при отладке
Суть проблемы. Пишу шаблон для TextBox. Простенький пример шаблона: &lt;TextBox...

VS ругается на $content. PHP0412 Use of unassigned variable 'content'
7 и 11 строка &lt;?php $styles = array('style.css'); class Rss { public function...

4
Модератор
Эксперт .NET
15466 / 10712 / 2786
Регистрация: 21.04.2018
Сообщений: 31,531
Записей в блоге: 2
02.12.2020, 10:47 2
Цитата Сообщение от Fiasqo Посмотреть сообщение
ColorAnimation не может работать с DynamicResource
???
Это DependencyObject и у него DP-свойства.
Не должно быть никаких проблем с DynamicResource.

Добавлено через 2 минуты
А зачем вам, вообще, здесь анимация?
Вы же почти мгновенно переходите к следующему значению?

Добавлено через 2 минуты
Просто в триггере IsMouseOver=True, добавьте два сеттера.

Добавлено через 2 минуты
Цитата Сообщение от Fiasqo Посмотреть сообщение
Поэтому я подумал решить эту проблему так: рисовать контент дважды(друг на друге),
назначив нужные цвета, а затем манипулировать прозрачностью:
В этом тоже нет необходимости.
У вас два абсолютно одинаковых UserControl.
Отличается только свойство Foreground.
Меняйте его значение в триггере задав сеттер.
0
18 / 5 / 2
Регистрация: 01.12.2020
Сообщений: 6
03.12.2020, 03:21  [ТС] 3
Цитата Сообщение от Элд Хасп Посмотреть сообщение
???
Это DependencyObject и у него DP-свойства.
Не должно быть никаких проблем с DynamicResource.
Я не могу свойству ColorAnimation.To установить динамический ресурс, потому что
*Цитирую msdn*
You can't use dynamic resource references or data binding expressions to set Storyboard or animation property values.
That's because everything inside a Style must be thread-safe...
При использование динамического ресурса, как и ожидалось, cразу падает исключение :
Код
System.InvalidOperationException: Cannot freeze this Storyboard timeline tree for use across threads.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
А зачем вам, вообще, здесь анимация?
Вы же почти мгновенно переходите к следующему значению?
Совсем не мгновенно:
Название: gifka.gif
Просмотров: 33

Размер: 31.6 Кб
0
Модератор
Эксперт .NET
15466 / 10712 / 2786
Регистрация: 21.04.2018
Сообщений: 31,531
Записей в блоге: 2
03.12.2020, 11:22 4
Цитата Сообщение от Fiasqo Посмотреть сообщение
Совсем не мгновенно:
Не хочу возиться с MaterialDesign.
Если сделаете пример (сокращённый насколько можно) без него - попробую разобраться.

Но анимация капризная вещь.
По сути она была сделана для использования в C#, а не XAML.
Потом дополнили библиотеку разными типами, чтобы можно было использовать в XAML.
Но всё равно многое из возможностей анимации в XAML "из коробки" не доступно или сделать трудно и неочевидно.
Часто бывает необходимость обратиться к C#.
1
18 / 5 / 2
Регистрация: 01.12.2020
Сообщений: 6
04.12.2020, 01:55  [ТС] 5
Лучший ответ Сообщение было отмечено Элд Хасп как решение

Решение

Смог добиться изначально желаемого эффекта анимации, используя ColorAnimation с динамическими ресурсами через
Attached Properties.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*    file0.cs    */
namespace YourNamespace.Assists {
public enum MaterialDesignBrush {
    PrimaryHueMidForegroundBrush,
    PrimaryHueLightForegroundBrush,
    PrimaryHueDarkForegroundBrush,
    SecondaryHueMidForegroundBrush,
    PrimaryHueMidBrush,
    PrimaryHueLightBrush,
    PrimaryHueDarkBrush,
    SecondaryHueMidBrush,
}
}
 
/*    file1.cs*/
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
 
namespace YourNamespace.Assists {
public class ButtonAssist {
    private static readonly Dictionary<Button, MaterialDesignBrush> _fromForegroundBrushes = new Dictionary<Button, MaterialDesignBrush>();
    private static readonly Dictionary<Button, MaterialDesignBrush> _toForegroundBrushes = new Dictionary<Button, MaterialDesignBrush>();
 
    public static readonly DependencyProperty AnimateMouseOverProperty = DependencyProperty.RegisterAttached(
        "AnimateMouseOver",
        typeof(bool),
        typeof(ButtonAssist),
        new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender, AnimateMouseOverChangedCallback));
 
    private static void AnimateMouseOverChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        if (!(d is Button button)) return;
        if ((bool) e.NewValue) {
            button.MouseEnter += ButtonOnMouseEnter;
            button.MouseLeave += ButtonOnMouseLeave;
        } else {
            _fromForegroundBrushes.Remove(button);
            _toForegroundBrushes.Remove(button);
            button.MouseEnter -= ButtonOnMouseEnter;
            button.MouseLeave -= ButtonOnMouseLeave;
        }
    }
 
    public static void SetAnimateMouseOver(DependencyObject element, bool value) => element.SetValue(AnimateMouseOverProperty, value);
 
    public static bool GetAnimateMouseOver(DependencyObject element) => (bool) element.GetValue(AnimateMouseOverProperty);
 
    public static void SetTo(DependencyObject element, MaterialDesignBrush value) {
        if (!(element is Button button)) return;
        if (_toForegroundBrushes.ContainsKey(button)) _toForegroundBrushes.Remove(button);
        _toForegroundBrushes.Add(button, value);
    }
 
    public static void SetFrom(DependencyObject element, MaterialDesignBrush value) {
        if (!(element is Button button)) return;
        if (_fromForegroundBrushes.ContainsKey(button)) _fromForegroundBrushes.Remove(button);
        _fromForegroundBrushes.Add(button, value);
    }
 
    private static void ButtonOnMouseEnter(object sender, MouseEventArgs e) {
        if (!(sender is Button button)) return;
        if (!_fromForegroundBrushes.ContainsKey(button)) return;
        if (!_toForegroundBrushes.ContainsKey(button)) return;
 
        button.Foreground = new SolidColorBrush(((SolidColorBrush) button.Foreground).Color);
        var foregroundColorAnimation = new ColorAnimation(
            ((SolidColorBrush) Application.Current.Resources[_fromForegroundBrushes[button].ToString()]).Color,
            ((SolidColorBrush) Application.Current.Resources[_toForegroundBrushes[button].ToString()]).Color,
            new Duration(TimeSpan.FromMilliseconds(200)));
        button.Foreground.BeginAnimation(SolidColorBrush.ColorProperty, foregroundColorAnimation);
    }
 
    private static void ButtonOnMouseLeave(object sender, MouseEventArgs e) {
        if (!(sender is Button button)) return;
        if (!_fromForegroundBrushes.ContainsKey(button)) return;
        if (!_toForegroundBrushes.ContainsKey(button)) return;
        
        button.Foreground = new SolidColorBrush(((SolidColorBrush) button.Foreground).Color);
        var foregroundColorAnimation = new ColorAnimation(
            ((SolidColorBrush) Application.Current.Resources[_toForegroundBrushes[button].ToString()]).Color,
            ((SolidColorBrush) Application.Current.Resources[_fromForegroundBrushes[button].ToString()]).Color,
            new Duration(TimeSpan.FromMilliseconds(200)));
 
        foregroundColorAnimation.Completed += (o, args) => {
            button.SetResourceReference(Control.ForegroundProperty, _fromForegroundBrushes[button].ToString());
        };
        button.Foreground.BeginAnimation(SolidColorBrush.ColorProperty, foregroundColorAnimation);
    }
}
}
1
04.12.2020, 01:55
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.12.2020, 01:55
Помогаю со студенческими работами здесь

Content-Language и Content-Type для оптимизации
Есть сайт на котором норм кол-во страниц но яндекс почему-то проиндексировал лишь 5 из них на всех...

Include 'content.php' вместо $content$
Здравствуйте уважаемые форумчане! Нужна ваша помощь. И так, например, в файле index.php имеется...

Несмотря того что я поставил <META content='text/html; charset=UTF-8' http-equiv=Content-Type>, в броузере она всеровно меняется.
Несмотря того что я поставил &lt;META content='text/html; charset=UTF-8' http-equiv=Content-Type&gt;, в...

Как избавится от Mime-Version: 1.0 Content-Type: text/plain Content-Transfer-Encoding: 7bit X-Mailer: Servlet Mailer ?
При отправке письма при помощи JavaMail В начале письма всегда стоит: Mime-Version: 1.0 ...

Supplied content type is not allowed. Content-Type: application/json is required что за ошибка?
Supplied content type is not allowed. Content-Type: application/json is required что за ошибка?

Ошибка "Mixed Content: . This request has been blocked; the content must be served over HTTPS."
Здравствуйте. Есть сайт, доступен по https. Однако, на сайте есть подгружаемый контент в iframe со...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru