#wpf #xaml #controltemplate
Вопрос:
Я новичок в WPF и пытаюсь придумать шаблон пользовательского стиля для a ToggleButton
. До сих пор мне удавалось определять пути с помощью кривых Безье, но я застрял в следующей проблеме:
- Как я могу объединить два
Path
s, чтобы при наведении курсораToggleButton
цвет в ОБОИХ ПУТЯХ менялся в соответствии с прикрепленным изображением. Должно быть два разных значения цвета, одно для основной части, а другое для синей полосы вверху. Вот часть моего холста в XAML:
<Canvas Width="180" Height="180" Canvas.Left="0" Canvas.Top="0" HorizontalAlignment="Center" VerticalAlignment="Top">
<Path Stretch="Fill" StrokeLineJoin="Miter" Stroke="#FFB5BECB" Fill="#FFEDF2F7" Data="F1 M 90,18C 109.882,18 127.882,26.0589 140.912,39.0883L 152.225,27.7746C 136.301,11.8497 114.301,2.00002 90,2.00002L 90,18 Z"/>
<Path Stretch="Fill" StrokeLineJoin="Miter" Stroke="#FFB5BECB" Fill="#FFCDD5DE" Data="F1 M 90,18C 109.882,18 127.882,26.0589 140.912,39.0883L 152.225,27.7746C 136.301,11.8497 114.301,2.00002 90,2.00002L 90,18 Z "/>
<Path Stretch="Fill" StrokeThickness="1" StrokeLineJoin="Miter" Stroke="#FF6F9FFF" Fill="#FF6F9FFF" Data="F1 M 89.9999,5.00005C 113.472,5.00005 134.722,14.514 150.104,29.896L 152.225,27.7746C 136.301,11.8497 114.301,2.00002 90,2.00002L 89.9999,5.00005 Z "/>
<Path Stretch="Fill" StrokeThickness="1" StrokeLineJoin="Miter" Stroke="#FF13487E" Fill="#FF13487E" Data="F1 M 89.9999,5.00005C 113.472,5.00005 134.722,14.514 150.104,29.896L 152.225,27.7746C 136.301,11.8497 114.301,2.00002 90,2.00002L 89.9999,5.00005 Z"/>
</Canvas>
На следующем рисунке показаны ожидаемое основное состояние и состояние наведения.
Ответ №1:
Вы можете назвать свои элементы, присвоив x:Name
им . Затем вы можете обратиться к ним в a Trigger
, который проверяет IsMouseOver
свойство родительского контейнера, например Canvas
.
Поскольку вы не предоставляете свой шаблон полного контроля, эта часть, которую вы опубликовали, адаптирована для изменения Stroke
s и Fill
Path
s при наведении курсора мыши.
<ToggleButton Content="Templated Toggle Button">
<ToggleButton.Template>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<!-- ...here might be a container that you did not provide in your question. -->
<Canvas x:Name="MyCanvas" Width="180" Height="180" Canvas.Left="0" Canvas.Top="0" HorizontalAlignment="Center" VerticalAlignment="Top">
<Path x:Name="TopPart" Stretch="Fill" StrokeLineJoin="Miter" Stroke="#FFB5BECB" Fill="#FFCDD5DE" Data="F1 M 90,18C 109.882,18 127.882,26.0589 140.912,39.0883L 152.225,27.7746C 136.301,11.8497 114.301,2.00002 90,2.00002L 90,18 Z "/>
<Path x:Name="BottomPart" Stretch="Fill" StrokeThickness="1" StrokeLineJoin="Miter" Stroke="#FF13487E" Fill="#FF13487E" Data="F1 M 89.9999,5.00005C 113.472,5.00005 134.722,14.514 150.104,29.896L 152.225,27.7746C 136.301,11.8497 114.301,2.00002 90,2.00002L 89.9999,5.00005 Z"/>
</Canvas>
<ControlTemplate.Triggers>
<Trigger SourceName="MyCanvas" Property="IsMouseOver" Value="True">
<Setter TargetName="TopPart" Property="Stroke" Value="#FFB5BECB"/>
<Setter TargetName="TopPart" Property="Fill" Value="#FFEDF2F7"/>
<Setter TargetName="BottomPart" Property="Stroke" Value="#FF6F9FFF"/>
<Setter TargetName="BottomPart" Property="Fill" Value="#FF6F9FFF"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
Обновите свой комментарий. Шаблон элемента управления может состоять из нескольких именованных частей и визуальных состояний, которые определяют внешний вид и поведение элемента управления. Некоторые детали могут даже потребоваться для правильной работы элемента управления. Вы можете найти их в документации по стилям и шаблонам с примерами, но имейте в виду, что они могут быть неполными.
В случае ToggleButton
, есть много визуальных состояний, например, наведение курсора мыши, Нажатие, Проверка и так далее. Вы можете просто определить раскадровки для каждого из них, чтобы определить внешний вид и переходы между состояниями. Этот подход использует VisualStateManager
, который является альтернативой стилям и триггерам. Существует множество учебных пособий. Ваш шаблон может выглядеть следующим образом. При необходимости добавляйте раскадровки в состояния. Более простым способом определения визуальных состояний, чем редактирование кода XAML, является использование Blend, где вы можете удобно редактировать их с помощью графического редактора. Обзор см. в разделе Blend 2015: Создание визуальных состояний или аналогичных руководствах.
<ToggleButton Content="Templated Toggle Button">
<ToggleButton.Template>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<!-- ...here might be a container that you did not provide in your question. -->
<Canvas x:Name="MyCanvas"
Width="180"
Height="180"
Canvas.Left="0"
Canvas.Top="0"
HorizontalAlignment="Center"
VerticalAlignment="Top">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke.(SolidColorBrush.Color)"
Storyboard.TargetName="TopPart">
<EasingColorKeyFrame KeyTime="0"
Value="#FFB5BECB" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
Storyboard.TargetName="TopPart">
<EasingColorKeyFrame KeyTime="0"
Value="#FFEDF2F7" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke.(SolidColorBrush.Color)"
Storyboard.TargetName="BottomPart">
<EasingColorKeyFrame KeyTime="0"
Value="#FF6F9FFF" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
Storyboard.TargetName="BottomPart">
<EasingColorKeyFrame KeyTime="0"
Value="#FF6F9FFF" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke.(SolidColorBrush.Color)"
Storyboard.TargetName="TopPart">
<EasingColorKeyFrame KeyTime="0"
Value="DarkRed" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
Storyboard.TargetName="TopPart">
<EasingColorKeyFrame KeyTime="0"
Value="Red" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke.(SolidColorBrush.Color)"
Storyboard.TargetName="BottomPart">
<EasingColorKeyFrame KeyTime="0"
Value="Blue" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
Storyboard.TargetName="BottomPart">
<EasingColorKeyFrame KeyTime="0"
Value="Blue" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled" />
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked" />
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Path x:Name="TopPart"
Stretch="Fill"
StrokeLineJoin="Miter"
Stroke="#FFB5BECB"
Fill="#FFCDD5DE"
Data="F1 M 90,18C 109.882,18 127.882,26.0589 140.912,39.0883L 152.225,27.7746C 136.301,11.8497 114.301,2.00002 90,2.00002L 90,18 Z " />
<Path x:Name="BottomPart"
Stretch="Fill"
StrokeThickness="1"
StrokeLineJoin="Miter"
Stroke="#FF13487E"
Fill="#FF13487E"
Data="F1 M 89.9999,5.00005C 113.472,5.00005 134.722,14.514 150.104,29.896L 152.225,27.7746C 136.301,11.8497 114.301,2.00002 90,2.00002L 89.9999,5.00005 Z" />
</Canvas>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
Комментарии:
1. Большое спасибо, что нашли для меня решение. Я могу разобраться с этим прямо сейчас! @thatguy
2. На самом деле мне нужны дополнительные состояния для
IsPressed
иIsChecked
(Свойства для aToggleButton
). К сожалению, они не работают с наличиемCanvas
в качестве контейнера, потомуCanvas
что у них есть другиеTemplate Properties
. У вас есть какие-нибудь идеи, что еще я мог бы положить в качестве контейнера для моегоpaths
? Заранее благодарю вас!3. Это здорово! Я займусь этим как можно скорее. Спасибо!