Загрузка данных
<Window x:Class="WpfSwitchesApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Переключатели" Height="450" Width="600"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<!-- Общий стиль для интерактивных переключателей -->
<Style x:Key="SwitchButtonStyle" TargetType="Button">
<!-- Сбрасываем стандартный фон и рамку кнопки Windows -->
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<!-- RenderTransformOrigin="0.5,0.5" центрирует масштабирование и поворот -->
<Grid Background="Transparent" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="TemplateScale" ScaleX="1" ScaleY="1"/>
<RotateTransform x:Name="TemplateRotate" Angle="0"/>
</TransformGroup>
</Grid.RenderTransform>
<!-- Внешний шестиугольник -->
<Polygon Points="30,0 90,0 120,52 90,104 30,104 0,52"
Fill="#D3D3D3" Stroke="#7A7A7A" StrokeThickness="2"
Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<!-- Внутренний серый круг -->
<Ellipse Width="70" Height="70" Fill="#BDBDBD" Stroke="#8C8C8C" StrokeThickness="1"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<!-- Поворотная ручка переключателя -->
<Grid Width="55" Height="55" HorizontalAlignment="Center" VerticalAlignment="Center">
<!-- Сам тумблер -->
<Rectangle Height="14" Fill="#A6A6A6" Stroke="#5A5A5A" StrokeThickness="1"
RadiusX="2" RadiusY="2"/>
<!-- Черная засечка (индикатор направления) слева -->
<Rectangle Width="15" Height="4" Fill="Black" HorizontalAlignment="Left" Margin="5,0,0,0"/>
</Grid>
</Grid>
<!-- Триггеры для анимации при наведении -->
<ControlTemplate.Triggers>
<!-- Увеличение переключателя при наведении курсора -->
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TemplateScale"
Storyboard.TargetProperty="ScaleX"
To="1.4" Duration="0:0:0.15"/>
<DoubleAnimation Storyboard.TargetName="TemplateScale"
Storyboard.TargetProperty="ScaleY"
To="1.4" Duration="0:0:0.15"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="TemplateScale"
Storyboard.TargetProperty="ScaleX"
To="1.0" Duration="0:0:0.15"/>
<DoubleAnimation Storyboard.TargetName="TemplateScale"
Storyboard.TargetProperty="ScaleY"
To="1.0" Duration="0:0:0.15"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<!-- Пропорциональная сетка: 3 равные колонки (требование 1) -->
<Grid Margin="30">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Три одинаковых переключателя, привязанных к одному обработчику клика -->
<Button Grid.Column="0" Style="{StaticResource SwitchButtonStyle}" Click="Switch_Click" Margin="20"/>
<Button Grid.Column="1" Style="{StaticResource SwitchButtonStyle}" Click="Switch_Click" Margin="20"/>
<Button Grid.Column="2" Style="{StaticResource SwitchButtonStyle}" Click="Switch_Click" Margin="20"/>
</Grid>
</Window>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace WpfSwitchesApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
/// <summary>
/// Обработчик клика по переключателю.
/// Плавно поворачивает элемент на 20 градусов по часовой стрелке.
/// </summary>
private void Switch_Click(object sender, RoutedEventArgs e)
{
if (sender is Button clickedButton)
{
// Проникаем внутрь визуального дерева шаблона кнопки
if (VisualTreeHelper.GetChildrenCount(clickedButton) > 0)
{
var templateRoot = VisualTreeHelper.GetChild(clickedButton, 0) as FrameworkElement;
if (templateRoot != null && templateRoot.RenderTransform is TransformGroup transformGroup)
{
// Ищем RotateTransform в группе трансформаций шаблона
foreach (var transform in transformGroup.Children)
{
if (transform is RotateTransform rotateTransform)
{
double currentAngle = rotateTransform.Angle;
double targetAngle = currentAngle + 20.0; // Прибавляем 20 градусов
// Создаем анимацию плавного изменения угла
DoubleAnimation rotateAnimation = new DoubleAnimation
{
From = currentAngle,
To = targetAngle,
Duration = TimeSpan.FromSeconds(0.25), // Время поворота (в секундах)
EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseOut } // Замедление в конце
};
// Применяем и запускаем анимацию на свойство Angle
rotateTransform.BeginAnimation(RotateTransform.AngleProperty, rotateAnimation);
break;
}
}
}
}
}
}
}
}