📖 wpf-behavior-practice - Git Hub にソースコードを置いたぜ
📖 wpf-action-practice - Git Hub にソースコードを置いたぜ
📖 wpf-command-practice - Git Hub にソースコードを置いたぜ
「 👆 2010年ぐらいの記事だが 古いソースも保守の対称だから ちょうどいいだろう。
ビヘイビア(Behavior)の使い方を覚えようぜ?」
using System.Windows.Interactivity;
📖 【WPF】System.Windows.Interactivityがない!
「 有るんだろうけど、細かなこと覚えるより Livet 使った方がよくない?」
「 👆 LivetCask を NuGet でインストールしたぜ」
using Microsoft.Xaml.Behaviors;
using System;
using System.Windows;
using System.Windows.Controls;
namespace WpfBehaviorPractice
{
/// <summary>
/// ボタンを押したら、警告ダイアログボックスが出るという振る舞い
/// </summary>
public class AlertBehavior : Behavior<Button>
{
public AlertBehavior()
{
}
/// <summary>
/// ダイアログボックスに表示する任意の文字列です
/// </summary>
public string Message
{
get { return (string)GetValue(MessageProperty); }
set { SetValue(MessageProperty, value); }
}
/// <summary>
/// Using a DependencyProperty as the backing store for Message. This enables animation, styling, binding, etc...
/// </summary>
public static readonly DependencyProperty MessageProperty =
DependencyProperty.Register("Message", typeof(string), typeof(AlertBehavior), new UIPropertyMetadata(null));
/// <summary>
/// 要素にアタッチされたときの処理。大体イベントハンドラの登録処理をここでやる
/// </summary>
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.Click += Alert;
}
/// <summary>
/// 要素にデタッチされたときの処理。大体イベントハンドラの登録解除をここでやる
/// </summary>
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.Click -= Alert;
}
/// <summary>
/// メッセージが入力されていたらメッセージボックスを出す
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Alert(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(this.Message))
{
return;
}
MessageBox.Show(this.Message);
}
}
}
「 👆 なんだか分かってないが だいたい コピー貼り付けだぜ」
「 👆 Assets から Button の上へ Behavior をドラッグ&ドロップすればいいらしいんだが、無いぜ Assets とか」
<Window x:Class="WpfBehaviorPractice.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfBehaviorPractice"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Content="適当に置いたボタン" HorizontalAlignment="Left" Height="72" Margin="323,202,0,0" VerticalAlignment="Top" Width="130"/>
</Grid>
</Window>
<Window x:Class="WpfBehaviorPractice.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfBehaviorPractice"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Content="適当に置いたボタン" HorizontalAlignment="Left" Height="72" Margin="323,202,0,0" VerticalAlignment="Top" Width="130">
<i:Interaction.Behaviors>
<local:AlertBehavior Message="こんにちは世界"/>
</i:Interaction.Behaviors>
</Button>
</Grid>
</Window>
「 👆 こうすりゃいいんだろ。 `xmlns:i="~" が増えてるの注意な」
「 ボタンだって マウスクリックをするというイベントもあれば マウスカーソルが重なるというイベントもあるだろ。
その書き方だと ボタンを押したときの振る舞いしか 書けなくないかだぜ?」
「 Trigger というのがあるらしいんだけど、難しそうだから 今はパスね」
「 👆 LivetCask を NuGet でインストールするって言って 何のことだか 通じているんだろうか?」
using Microsoft.Xaml.Behaviors;
using System.Windows;
using System.Windows.Controls;
namespace WpfActionPractice
{
/// <summary>
/// ボタンを押したら、警告ダイアログボックスが出るということ
/// </summary>
public class AlertAction : TriggerAction<Button>
{
/// <summary>
/// ダイアログボックスに表示する任意の文字列です
/// </summary>
public string Message
{
get { return (string)GetValue(MessageProperty); }
set { SetValue(MessageProperty, value); }
}
public static readonly DependencyProperty MessageProperty =
DependencyProperty.Register("Message", typeof(string), typeof(AlertAction), new UIPropertyMetadata(null));
public AlertAction()
{
}
/// <summary>
/// メッセージが入力されていたらメッセージボックスを出す
/// </summary>
/// <param name="o"></param>
protected override void Invoke(object o)
{
if (string.IsNullOrEmpty(this.Message))
{
return;
}
MessageBox.Show(this.Message);
}
}
}
「 👆 なんか コード量減ったな。 Behavior と似ているようでいて、ところどころ Behavior とも違うし」
<Window x:Class="WpfActionPractice.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfActionPractice"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Content="適当に置いたボタン" HorizontalAlignment="Left" Height="93" Margin="315,176,0,0" VerticalAlignment="Top" Width="134"/>
</Grid>
</Window>
「 👆 アクションをコーディングする前の、 .xaml はこんな感じ」
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
「 👆 ここに、これから xml namespace属性、つまり xmlns なんだが、 xmlns:i="~"
を追加するのが 要点みたいだな」
<Window x:Class="WpfActionPractice.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfActionPractice"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Button Content="適当に置いたボタン" HorizontalAlignment="Left" Height="93" Margin="315,176,0,0" VerticalAlignment="Top" Width="134">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<local:AlertAction Message="こんにちはアクション"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</Window>
「 👆 そしてこれが アクションをコーディングした .xaml だぜ」
「 あっ、 i:EventTrigger
ってのがある! Trigger だぜ!
EventName="Click"
って書いてるぜ!」
「 👆 ボタンをクリックしたら ダイアログボックスが出てきたぜ。 でけたな」
「 アクションの方が 多くの要望に応えられそうじゃないかだぜ? ビヘイビアって 仕事で出てくる要望をこなせるのかだぜ?」
「 そこらへんの ドメイン知識が インターネット上の記事にないのよね。
どう使い分けて 1つのアプリケーションを作り上げていくのか 見えないわねえ。 画面1つ作るだけなら できそうだけど」
「 👆 NuGetを使って、LivetCask をインストール」
「 👆 とりあえず RoutedCommandプロパティを置いてみようぜ」
<Window x:Class="WpfCommandPractice.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfCommandPractice"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
<Window x:Class="WpfCommandPractice.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfCommandPractice"
mc:Ignorable="d"
Title="MainWindow" Height="143" Width="410">
<Window.CommandBindings>
<CommandBinding
Command="{x:Static local:MainWindow.AlertCommand}"
Executed="CommandBinding_Executed"
CanExecute="CommandBinding_CanExecute"/>
</Window.CommandBindings>
<Grid>
</Grid>
</Window>
「 👆 じゃあ 足りてないとエラーが出てるやつを 先に追加したろ」
「 👆 そして CanExecuteチェックボックスと AlterCommandボタンを追加だぜ。
.xaml を直接編集するぜ」
<Window x:Class="WpfCommandPractice.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfCommandPractice"
mc:Ignorable="d"
Title="MainWindow" Height="143" Width="410">
<Window.CommandBindings>
<CommandBinding
Command="{x:Static local:MainWindow.AlertCommand}"
Executed="CommandBinding_Executed"
CanExecute="CommandBinding_CanExecute"/>
</Window.CommandBindings>
<Grid>
<StackPanel>
<CheckBox x:Name="checkBox" Content="CanExecute"/>
<Button Content="AlertCommand" Command="{x:Static local:MainWindow.AlertCommand}" />
</StackPanel>
</Grid>
</Window>
using System.Windows;
using System.Windows.Input;
namespace WpfCommandPractice
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
/// <summary>
/// ユーザーのアクションと、その処理を結びつけるもの
/// </summary>
public static RoutedCommand AlertCommand = new RoutedCommand();
public MainWindow()
{
InitializeComponent();
}
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Hello world");
}
private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = this.checkBox.IsChecked.Value;
}
}
}
「 👆 チェックボックスをチェックすると ボタンが活性化したな」
「 👆 ボタンをクリックすると、なんか離れたところに ダイアログボックスが出てきたぜ。
このダイアログボックスは OKボタンを押して閉じないと、親ウィンドウは マウスで触れないぜ」
「 👆 チェックボックスを外すと また ボタンが不活性になったぜ」
「 CanExecute で活性/不活性を .xaml に書けるぐらいしか アクションと違いが分からないぜ」
「 分からないことだらけだな。 どう使い分けたらいいのか?」
「 👆 コマンドには キー・バインディング もできるようだぜ。
ボタンが活性のとき ショートカット・キーで ボタン押せた。 これは コマンドだけだよな」
Crieitは個人で開発中です。
興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!