Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 5.00/25: Рейтинг темы: голосов - 25, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 17.02.2015
Сообщений: 49

Кнопка с несколькими объектами Path

05.12.2016, 22:22. Показов 5420. Ответов 25

Студворк — интернет-сервис помощи студентам
Доброго времени суток.

Хотел бы открыть топик, в котором буду задавать вопросы более опытным коллегам и постить свой прогресс по теме, т.к. задача, хоть и тривиальная по идее, в реализации сильно отличается от большинства примеров и простых заданий, существующих на сайте и, как мне кажется, в будущем сможет помочь многим.

Есть задача, создать WPF сложную кнопку почты, на которой вместо обычного текста будет присутствовать:
- рисунок с изображением(2) (например конвертика);
- на момент подгруздки писем поверх основного рисунка, в определенном красотой месте, крутится рисунок отображающий загрузку писем(3) (а-ля стрелочки в кружочке)
- после загрузки, - текст отображающий сколько непрочитанных писем у пользователя(4), если они есть
- анимация подсветки кнопки, если письма есть(5).

После некоторого гугла было решено следующее:

1. Для применения собственных свойств к кнопке использовать стиль, в который поместить свои изыски со шрифтами и шаблон, содержащий вышеописанные дополнения.
2. В качестве основного рисунка был выбран векторный вариант картинки, реализованный с помощью объекта Path:
XML
1
2
3
4
5
6
7
8
9
10
11
<Path x:Key="Mail" Data="
          M 0, 5.5 L 17.5, 5.5 C 17.4, 6 17.4, 6.3
          17.4, 6.7 17.4, 8.3 17.8, 9.8 18.7, 11.1 L 13.78, 14.2z 
          
          M 0, 5.5 L 13.8, 17 19.6, 12.1 C 21, 13.6 
          23, 14.6 25.3, 14.6 26, 14.6 26.8, 14.5
          27.5, 14.3 L 27.5 22 27.3, 21.9 27.5, 22
          0, 22 0.1, 21.9 0, 22z"
           Stretch="Uniform" Fill="#FFFFFFFF" Width="50" Height="50" 
          Margin="0,0,0,0" RenderTransformOrigin="0.5,0.5">
    </Path>
Изображение, в принципе, можно без труда конвертить из фотошопоподобных программ путем юзания плагина, или же взять готовые бесплатные, например отсюда.
С векторным изображением в WPF, как кажется, проще работать т.к. сам WPF векторный, и, в частности, применять анимацию. (Так ли это?)
Как видно из врезки кода выше, картинка создана с помощью встроенного языка описания геометрии, сведения о котором, в целом, найти не сложно.
3. В качестве рисунка на момент загрузки, выбран следующий рисунок
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
<Path x:Key="MailSync" Data="
          M 20.3, 6.3659973 L 21.1, 10.5 22.1, 9.7 C 23, 10.5 24.2, 11 25.5, 10.9 26.7, 10.7 27.6, 
          10.2 28.3, 9.4 L 27.4, 9 C 26.9, 9.5 26.2, 9.9 25.4, 9.9 24.4, 10 23.5, 9.7 22.8, 9 L 24.3, 7.8z 
          
          M 25.1, 2.2 C 24.5, 2.25 24.9, 2.3 24.6, 2.3 23.5, 2.4 22.5, 3 21.8, 3.8 L 22.7, 4.1 C 23.2, 3.6 24, 3.3 
          24.7, 3.2 25.8, 3.1 27, 3.5 27.6, 4.3 L 26.3, 5.5 30.2, 7 29.4 ,2.8 28.3, 3.7 C 27.5, 2.8, 26.4, 2.2, 25.2, 2.2z
          
          M 25.3, 0 C 29, 0 32, 3 32, 6.7 32, 10.4 29, 13.4 25.3, 13.4 21.6, 13.4 18.6, 10.4 18.6, 6. 18.6, 3 21.6, 0 25.3,0z
          "
          Stretch="Uniform" Fill="#FFFFFFFF" Width="50" Height="50" 
          Margin="0,0,0,0" RenderTransformOrigin="0.5,0.5">
        
    </Path>
.
4. Для отображения информации о полученных письмах видится создание контейнера, в который ляжет картинка для красивости фона и TextBlock для отображения количества писем. Чтобы иметь возможность удобно засылать контент думалось создать свойство зависимости, отвечающее за текст в TextBlock
5. Для создания анимации думал создать в шаблоне триггер, отвечающий за свойство Fill элементов типа Path и событие, которое будет его включать.

Собственно вопросы:
Есть ли какие-то реальные примеры подобного контрола? (В интернете в основном либо куски, либо простые примеры. Это, отчасти и послужило толчком для написания поста.)
Как будет лучше организовать структуру такого контрола?
Вопрос, на котором я повис на данном этапе - Как правильно группировать элементы типа Path в одну структуру?

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

Код стиля, который есть сейчас приаттачил как .log файл.

Большое спасибо за помощь.
Вложения
Тип файла: log BasicButtonDictionary.log (5.8 Кб, 2 просмотров)
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.12.2016, 22:22
Ответы с готовыми решениями:

[WPF] "Path" является неоднозначной ссылкой между "System.Windows.Shapes.Path" и "System.IO.Path"
Здравствуйте! Делаю экспорт из программы в Excel. Код брался от WinForm, немного переписал. Задача была следующей: взять запись из...

Работа с несколькими jquery-объектами
Правильно ли будет обращение сразу к нескольким объектам так: var h2 = $('h2'), ul = $('.ul-kinds'); (h2, ul).fadeOut(2000); ...

Децентрализованное управление несколькими объектами
Имеется туннель в котором появляются различного рода препятствия(буквы Г или просто перегородки и тому прочее). Так же имеются несколько...

25
0 / 0 / 0
Регистрация: 17.02.2015
Сообщений: 49
12.12.2016, 14:15  [ТС]
Студворк — интернет-сервис помощи студентам
Спасибо большое.

Ошибки исчезли после того, как унаследовал целевой класс от класса Button.
Ранее было наследовано от UIElement. При сборке, видимо, чего-то не хватало, класс не собирался и это интерпретировалось как ошибка XAML, наверное потому, что intelisence не видел сигнатуры целевого класса.
Сейчас буду курить почему именно Button.

Добавлено через 30 минут
Посмотрев структуру классов, стало ясно, что наследоваться от UIElement смысла нет и проблема была в том, что в этом классе не определены почти никакие свойства, относящиеся к какому-либо конкретному контролу.

На данный момент, унаследовался от класса Control ниже по иерархии наследования.
0
0 / 0 / 0
Регистрация: 17.02.2015
Сообщений: 49
13.12.2016, 21:18  [ТС]
Цитата Сообщение от novikov.ea Посмотреть сообщение
Можно, написав так: <ContentControl Content="{StaticResource *Имя_Элемента*}" />
А можно управлять этим экземпляром ресурса из ContentControl'a через, например, триггеры?
Например, поменять ему свойство Fill?
0
Эксперт .NET
 Аватар для novikov.ea
1857 / 1363 / 429
Регистрация: 10.06.2011
Сообщений: 2,136
14.12.2016, 10:38
Вообще я не видел, чтобы кто-то делал представленным способом. Всё содержимое ControlTemplate описывается прямо в нём. Вы писали, что ваш Path - это ресурс, значит вы хотите, использовать его с нескольких местах. Но поскольку Path - это ресурс, то изменение его будет применяться ко всем местам, где он будет использоваться. Это точно то, что вам нужно? Может быть будет лучше просто прописать Path непосредственно в ControlTemplate?
Я не знаю специфики вашей задачи. Просто описал своё видение.
1
0 / 0 / 0
Регистрация: 17.02.2015
Сообщений: 49
15.12.2016, 13:38  [ТС]
Есть еще вопрос по теме: Есть ли способ применить анимацию, объявленную в ресурсе к разным объектам?
Воможно ответ кроется где-то на поверхности, но гугл показывает какие-то страшные манипуляции, аж не по себе

Например.
Есть шаблон для кнопки, в нем размещен контейнер и объекты типа Path:
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
<ControlTemplate x:Shared="False" x:Key="SpecButtonTemplate" TargetType="Button">
        <Border  BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}" 
                    Background="{TemplateBinding Background}" SnapsToDevicePixels="true" 
                    MinWidth="{TemplateBinding MinWidth}" MinHeight="{TemplateBinding MinHeight}">
 
            <Grid HorizontalAlignment="Center" VerticalAlignment="Center"
                        MinHeight="68" MinWidth="68" >
                
                <Canvas Height="42.5" Width="60.25"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center">
   <!--Целевой объект-->
                    <Path x:Name="Mail" Canvas.Top="2.25" Canvas.Left="5" Data="
                            M 0, 5.5 L 17.5, 5.5 C 17.4, 6 17.4, 6.3
                            17.4, 6.7 17.4, 8.3 17.8, 9.8 18.7, 11.1 L 13.78, 14.2z 
          
                            M 0, 5.5 L 13.8, 17 19.6, 12.1 C 21, 13.6 
                            23, 14.6 25.3, 14.6 26, 14.6 26.8, 14.5
                            27.5, 14.3 L 27.5 22 27.3, 21.9 27.5, 22
                            0, 22 0.1, 21.9 0, 22z"
                            Stretch="Uniform"  Width="50" Height="50" 
                            Margin="0,0,0,0" RenderTransformOrigin="0.5,0.5"
                            Effect="{StaticResource ShadowButtonEffect}">
                    </Path>
...
У шаблона есть триггеры, где хотелось бы применить анимацию:
XML
1
2
3
4
<ControlTemplate.Triggers>
            <EventTrigger RoutedEvent="FrameworkElement.Loaded">
<!--Здесь необходимо применить анимацию-->                        
            </EventTrigger>
Есть Storyboard, размещенный в ресурсе:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Storyboard x:Key="butBackground" RepeatBehavior="Forever">
        <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
            <EasingColorKeyFrame KeyTime="0" Value="#FFF1EBD5"/>
            <EasingColorKeyFrame KeyTime="0:0:0.25" Value="#FFFF5D11"/>
            <EasingColorKeyFrame KeyTime="0:0:0.3" Value="Red"/>
            <EasingColorKeyFrame KeyTime="0:0:0.35" Value="#FFFF5D11"/>
            <EasingColorKeyFrame KeyTime="0:0:0.8" Value="#FFF1EBD5"/>
            <EasingColorKeyFrame KeyTime="0:0:1.1" Value="#FFF1EBD5"/>
        </ColorAnimationUsingKeyFrames>
        <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
            <EasingColorKeyFrame KeyTime="0:0:0.2" Value="#FFF1EBD5"/>
            <EasingColorKeyFrame KeyTime="0:0:0.3" Value="#FFFF5D11"/>
            <EasingColorKeyFrame KeyTime="0:0:0.325" Value="Red"/>
            <EasingColorKeyFrame KeyTime="0:0:0.35" Value="#FFFF5D11"/>
            <EasingColorKeyFrame KeyTime="0:0:0.8" Value="#FFF1EBD5"/>
            <EasingColorKeyFrame KeyTime="0:0:1.1" Value="#FFF1EBD5"/>
        </ColorAnimationUsingKeyFrames>
    </Storyboard>
StoryBoard такой, потому что анимируется градиентная заливка. И вынесен в ресурс, потому что применяться он будет в большом количестве мест.
Эксперименты с Blend показали, что тамошний генератор всегда создает элемент ColorAnimationUsingKeyFrames заточенный под конкретный объект, путем задания параметров, типа таких:
XML
1
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="Mail">
При моих ныненшних знаниях, Storyboard.TargetName="Mail" сводит на нет возможность переиспользования анимации для других объектов того же типа.

Как и что необходимо модифицировать, чтобы имелась возможность использовать Storyboard для разных объектов одного типа?

Спасибо.
0
Эксперт .NET
 Аватар для novikov.ea
1857 / 1363 / 429
Регистрация: 10.06.2011
Сообщений: 2,136
15.12.2016, 14:06
Я с анимациями сам сало работал, может, чего не знаю. Но можно, как вариант, брать Storyboard-ресурс и запускать его.
Попробуйте создать свой наследник TriggerBase<>, который будет вызывать запуск анимации. Передавайте ему значения: EventTargetObject, RoutedEvent, Storyboard, StoryboardTargetObject. Попробуйте покопать у этом направлении.
Или, может, кто-то более опытный в деле анимаций подскажет.
0
0 / 0 / 0
Регистрация: 17.02.2015
Сообщений: 49
15.12.2016, 16:18  [ТС]
Вы говорите о коде C#. Я же думал, может быть, существует решение, при котором получится это сделать средствами XAML.

Нашел достаточно интересное решение, но оно относится не к шаблону, а к стилю и мной еще не опробовано.
Судя по всему, человек сделал прокладку в виде Объекта UIElement и свойства Opacity.

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<Window.Resources>
    <UIElement x:Key="AnimationPlaceholder" Opacity="0"/>
 
    <Style TargetType="TextBlock">
        <Setter Property="Opacity" 
                Value="{Binding Source={StaticResource AnimationPlaceholder}, Path=Opacity}" />
    </Style>
    
    <Storyboard x:Key="OnClick1">
        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                                       Storyboard.Target="{StaticResource AnimationPlaceholder}" 
                                       Storyboard.TargetProperty="(UIElement.Opacity)">
            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
            <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
    
    <Window.Triggers>
        <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button">
            <BeginStoryboard Storyboard="{StaticResource OnClick1}"/>
        </EventTrigger>
    </Window.Triggers>
</Window.Resources>
Неужели нужно прибегать к таким хитростям, чтобы решить простую проблему?))
Должно же быть какое-то решение вопроса)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
15.12.2016, 16:18

Работа с несколькими объектами на форме
Чтобы к примеру обратиться например к разным Picturebox-ам можно использовать такой код: Private Sub PictureBox_Click(ByVal sender As...

Как уменьшить расстояние между несколькими объектами?
Как уменьшить расстояние между несколькими объектами?)

Буфер трафарета для сцены с несколькими объектами
Сделать вырез в фигуре с использованием буфера трафарета несложно, в сети примеров хватает. Но что-то у меня некорректно работает для...

Инициализация вектора с несколькими типами данных или объектами класса
Задача наподобие книжной библиотеки. Есть класс Book в котором перечислены автор,название,год издания. Хочу создать отдельный класс...

Разработать программу, которая моделирует определенную последовательность действий с несколькими объектами
Разработать программу, которая моделирует определенную последовательность действий с несколькими объектами. Объекты находятся на разных...


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

Или воспользуйтесь поиском по форуму:
26
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru