この記事は
XAMLのボタン/ラベルに関する覚え書き
- ボタンの上にマウスを置くと、ボタンの色が変わる
- 照光式押しボタン (と、それに連動する何か)
- 警告点滅表示
1. ボタンの上にマウスを置くと、ボタンの色が変わる
マイクロソフトの公式ドキュメントを参照する
ボタンの上にマウスを置く(MouseOver)と、ボタンの色が変わる
依存関係プロパティ値の優先順位 - Microsoft Docsよりキャプチャ抜粋
Button インスタンスからローカル値の Red を削除すると、スタイルが優先されるようになり、ボタンの Background の値はスタイルから取得されます。 スタイル内ではトリガーが優先されるので、ボタンはマウスでポイントすると青になり、それ以外の場合は緑になります。
先頭のButton
タグからBackground="Red"
を削除すれば所望の動きになりそうだが、実際はそうではない。
このままだと、マウスオーバーしてもデフォルトの色が優先されて、青色にはならない。
Template
プロパティの変更をあらたに追加する必要がある。
Change color of Button when Mouse is over - Stack Overflow
-<Button Background="Red">
+<Button>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green" />
+ <Setter Property="Template">
+ <Setter.Value>
+ <ControlTemplate TargetType="{x:Type Button}">
+ <Border Background="{TemplateBinding Background}">
+ <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
+ </Border>
+ </ControlTemplate>
+ </Setter.Value>
+ </Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
Click
</Button>
個人的にはBorder
で囲むよりは、Grid
で囲むほうが好み。
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border Background="{TemplateBinding Background}"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
参考にしたサイト
マイクロソフト
ほか
2. 照光式押し釦
押すと光るボタンをつくる
イメージ
緑ベースのボタンを押すと、色が明るくなるイメージ
Style
<Style x:Key="ToggleStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="FontSize" Value="18" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="5" />
<Setter Property="Cursor" Value="Hand" />
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="LightGreen" />
<Setter Property="Foreground" Value="DarkBlue" />
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0.5, 1">
<GradientStop Offset="0" Color="Black" />
<GradientStop Offset="1" Color="Gray" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" Value="DarkGreen" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
ControlTemplete
<ControlTemplate x:Key="ToggleTemplate" TargetType="{x:Type ToggleButton}">
<Grid>
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="2">
<Border.Effect>
<DropShadowEffect
x:Name="shadowEffect"
BlurRadius="6"
Direction="-90"
RenderingBias="Quality"
ShadowDepth="0" />
</Border.Effect>
</Border>
<ContentPresenter
x:Name="content"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="content" Property="RenderTransform">
<Setter.Value>
<TranslateTransform X="1.5" Y="2.5" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
ボタンと、連動する何か
このボタンが押されたときに、他のなにかのスタイルを変える
<!-- きっかけのボタン -->
<ToggleButton
x:Name="StartButton"
...
Style="{StaticResource ToggleStyle}"
Template="{StaticResource ToggleTemplate}" />
<!-- ボタンと連動する何か -->
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=StartButton, Path=IsChecked}" Value="True">
<Setter Property="Width" Value="100" />
<Setter Property="Fill" Value="Aqua" />
</DataTrigger>
</Style.Triggers>
参考にしたサイト
マイクロソフト
スタックオーバーフロー
- Conditional styling of an element in XAML
- Change the background color of a toggle button when the toggle button is checked
ほか
3. 警告点滅表示
プロパティがtrue
の時だけ点滅するラベルをつくる
イメージ
Click!!
を押すとCaution!!
ラベルが赤く点滅する
View
xxx.Resources
にまとめずに一筆書きしたら、ネストがとても深くなった
<Window
x:Class="Project2107.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
Width="200"
Height="200"
prism:ViewModelLocator.AutoWireViewModel="True">
<StackPanel>
<Label
Margin="10"
Background="Red"
Content="Caution !!"
FontSize="12"
Foreground="white">
<Label.Style>
<Style TargetType="{x:Type Label}">
<Style.Triggers>
<DataTrigger Binding="{Binding Flag.Value}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<!-- trueの時のアニメーション -->
<Storyboard>
<DoubleAnimationUsingKeyFrames
AutoReverse="True"
RepeatBehavior="Forever"
Storyboard.TargetProperty="Opacity">
<LinearDoubleKeyFrame KeyTime="0:0:1.2" Value="1" />
<LinearDoubleKeyFrame KeyTime="0:0:0.6" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<!-- falseの時のアニメーション -->
<Storyboard>
<DoubleAnimationUsingKeyFrames
AutoReverse="True"
RepeatBehavior="Forever"
Storyboard.TargetProperty="Opacity">
<LinearDoubleKeyFrame KeyTime="0:0:1" Value="1" />
<LinearDoubleKeyFrame KeyTime="0:0:1" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
<Button Command="{Binding Command}" Content="Click!!" />
</StackPanel>
</Window>
ViewModel
ボタンをクリックすると、フラグのON/OFFが入れ替わる
フラグのON/OFFに応じて、Viewの点滅がスタート/ストップする
using Prism.Mvvm;
using Reactive.Bindings;
using System.Diagnostics;
namespace Project2107.ViewModels
{
public class MainWindowViewModel : BindableBase
{
public ReactiveProperty<bool> Flag { get; private set; } = new ReactiveProperty<bool>(true);
public ReactiveCommand Command { get; } = new ReactiveCommand();
public MainWindowViewModel()
{
Command.Subscribe(() => {
Flag.Value = !Flag.Value;
Debug.WriteLine($"{Flag.Value}");
});
}
}
}