それってスゴイ便利じゃん!
ってことで調べてみました。
UI オートメーションには、4つのコンポーネントがあるみたいです。
- UIAutomationClient
- UIAutomationClientsideProviders
- UIAutomationProvider
- UIAutomationTypes
今回は、UIAutomationClient と UIAutomationTypes を参照設定に追加して始めます。
using System;
using Livet;
using Livet.Commands;
/// <summary>
/// <see cref="System.Windows.Controls.Button"/> の ViewModel の機能を提供します。
/// </summary>
public class ButtonViewModel : ViewModel
{
#region Private fields
/// <summary>
/// コンテンツ。
/// </summary>
private object content;
/// <summary>
/// コマンド。
/// </summary>
private ViewModelCommand command;
/// <summary>
/// コマンドが実行可能かどうかの値。
/// </summary>
private bool canExecute;
/// <summary>
/// コマンドが実行可能かどうかが変化したことを自動通知するかどうかの値。
/// </summary>
private bool autoRaiseCanExecuteChanged;
/// <summary>
/// コマンドが実行するメソッド。
/// </summary>
private Action execute;
#endregion // Private fields
#region Constructors
/// <summary>
/// <see cref="ButtonViewModel"/> クラスの新しいインスタンスを初期化します。
/// </summary>
/// <param name="execute">コマンドが実行するメソッド。</param>
/// <exception cref="ArgumentNullException"><c>execute</c> が null です。</exception>
public ButtonViewModel(Action execute)
: this(execute, true, true)
{
}
/// <summary>
/// <see cref="ButtonViewModel"/> クラスの新しいインスタンスを初期化します。
/// </summary>
/// <param name="execute">コマンドが実行するメソッド。</param>
/// <param name="canExecute">コマンドが実行可能かどうかの値。</param>
/// <exception cref="ArgumentNullException"><c>execute</c> が null です。</exception>
public ButtonViewModel(Action execute, bool canExecute)
: this(execute, canExecute, true)
{
}
/// <summary>
/// <see cref="ButtonViewModel"/> クラスの新しいインスタンスを初期化します。
/// </summary>
/// <param name="execute">コマンドが実行するメソッド。</param>
/// <param name="canExecute">コマンドが実行可能かどうかの値。</param>
/// <param name="autoRaiseCanExecuteChanged">コマンドが実行可能かどうかが変化したことを自動通知するかどうかの値。</param>
/// <exception cref="ArgumentNullException"><c>execute</c> が null です。</exception>
public ButtonViewModel(Action execute, bool canExecute, bool autoRaiseCanExecuteChanged)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
this.execute = execute;
this.canExecute = canExecute;
this.autoRaiseCanExecuteChanged = autoRaiseCanExecuteChanged;
}
#endregion // Constructors
#region Properties
/// <summary>
/// コンテンツを取得または設定します。
/// </summary>
public object Content
{
get { return this.content; }
set
{
if (value != this.content)
{
this.content = value;
this.RaisePropertyChanged(() => this.Content);
}
}
}
/// <summary>
/// コマンドを取得します。
/// </summary>
public ViewModelCommand Command
{
get
{
return this.command = this.command ??
new ViewModelCommand(this.execute, () => this.CanExecute);
}
}
/// <summary>
/// コマンドが実行可能かどうかの値を取得または設定します。
/// </summary>
public bool CanExecute
{
get { return this.canExecute; }
set
{
if (value != this.canExecute)
{
this.canExecute = value;
this.RaisePropertyChanged(() => this.CanExecute);
if (this.AutoRaiseCanExecuteChanged)
{
this.RaiseCanExecuteChanged();
}
}
}
}
/// <summary>
/// コマンドが実行可能かどうかが変化したことを自動通知するかどうかの値を取得または設定します。
/// </summary>
public bool AutoRaiseCanExecuteChanged
{
get { return this.autoRaiseCanExecuteChanged; }
set
{
if (value != this.autoRaiseCanExecuteChanged)
{
this.autoRaiseCanExecuteChanged= value;
this.RaisePropertyChanged(() => this.AutoRaiseCanExecuteChanged);
}
}
}
#endregion // Properties
#region Public methods
/// <summary>
/// コマンドを実行します。
/// </summary>
public void Execute()
{
if (this.command != null)
{
this.Command.Execute();
}
}
/// <summary>
/// コマンドが実行可能かどうかが変化したことを通知します。
/// </summary>
public void RaiseCanExecuteChanged()
{
if (this.command != null)
{
this.command.RaiseCanExecuteChanged();
}
}
#endregion // Public methods
}
public MainWindowViewModel()
{
this.CopyButton = new ButtonViewModel(this.CopyAction)
{
Content = "コピー",
};
}
public ButtonViewModel CopyButton { get; private set; }
private void CopyAction()
{
}
<Button Command="{Binding Path=CopyButton.Command}"
Width="75"
Height="24"
Margin="3"
HorizontalAlignment="Right"
Content="{Binding Path=CopyButton.Content" />
private string inputText;
public string InputText
{
get { return this.inputText; }
set
{
if (value != this.inputText)
{
this.inputText = value;
this.RaisePropertyChanged(() => this.InputText);
}
}
}
private string outputText;
public string OutputText
{
get { return this.outputText; }
private set
{
if (value != this.outputText)
{
this.outputText = value;
this.RaisePropertyChanged(() => this.outputText);
}
}
}
private void CopyAction()
{
this.OutputText = this.InputText;
}
private ViewModelCommand copyCommand;
public ViewModelCommand CopyCommand
{
get
{
return this.copyCommand = this.copyCommand ??
new ViewModelCommand(this.CopyAction);
}
}
<Window x:Class="Kaznagamine.LivetSample.Views.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/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
xmlns:v="clr-namespace:Kaznagamine.LivetSample.Views"
xmlns:vm="clr-namespace:Kaznagamine.LivetSample.ViewModels"
Title="MainWindow" Height="300" Width="400">
<Window.DataContext>
<vm:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Path=InputText}"
Width="120"
Height="23"
Margin="3"
TextAlignment="Right" />
<Button Command="{Binding Path=CopyCommand}"
Width="75"
Height="24"
Margin="3"
HorizontalAlignment="Right"
Content="コピー" />
<TextBox Text="{Binding Path=OutputText}"
Width="120"
Height="23"
Margin="3"
TextAlignment="Right"
IsReadOnly="True"/>
</StackPanel>
</Grid>
</Window>