View内のUI操作のみでコントロールのプロパティの値を変更する
自前クラスのBooleanのプロパティをView内のUI操作だけで変更したかったので作ったActionのメモ
using System; using System.Reflection; using System.Windows; using System.Windows.Interactivity; namespace ToggleBoolPropertySample { /// <summary> /// Booleanプロパティの値を切り替えるアクション /// </summary> public class ToggleBoolPropertyAction : TargetedTriggerAction<DependencyObject> { protected override void Invoke(object parameter) { //プロパティおよび変更対象のエレメントが取得できていれば if (Target != null && PropertyName != null) { //プロパティ情報を取得 Type t = Target.GetType(); PropertyInfo propertyInfo = t.GetProperty(PropertyName); //プロパティタイプがboolの場合の処理 if (propertyInfo != null && propertyInfo.PropertyType == typeof(bool)) { var currentVal = (bool)propertyInfo.GetValue(Target, null); var newValue = currentVal ? false : true; propertyInfo.SetValue(Target, newValue, null); } //プロパティタイプがbool?の場合の処理 else if(propertyInfo != null && propertyInfo.PropertyType == typeof(bool?)) { var currentVal = (bool?)propertyInfo.GetValue(Target, null); //値がnullの場合は何もしない if (currentVal == null) { return; } var newValue = currentVal == true ? false : true; propertyInfo.SetValue(Target, newValue, null); } } } #region PropertyName Dependency Property public static readonly DependencyProperty PropertyNameProperty = DependencyProperty.Register("PropertyName", typeof(string), typeof(ToggleBoolPropertyAction), new PropertyMetadata(null)); /// <summary> /// 変更対象のプロパティ名 /// </summary> public string PropertyName { get { return (string)this.GetValue(PropertyNameProperty); } set { this.SetValue(PropertyNameProperty, value); } } #endregion } }
使い方:
<Window x:Class="ToggleBoolPropertySample.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:local="clr-namespace:ToggleBoolPropertySample" Title="MainWindow" Height="350" Width="525"> <Grid> <StackPanel Orientation="Vertical"> <CheckBox x:Name="TestCheckBox" Content="チェックボックス" IsChecked="True" Height="25" Width="100" Margin="30" /> <Button x:Name="TestCheckButton" Content="ボタン" IsEnabled="True" Height="25" Width="100" Margin="30" /> <Rectangle Width="100" Height="100" Margin="30" Fill="Aqua"> <i:Interaction.Triggers> <i:EventTrigger EventName="MouseEnter"> <local:ToggleBoolPropertyAction TargetName="TestCheckBox" PropertyName="IsChecked" /> </i:EventTrigger> <i:EventTrigger EventName="MouseLeave"> <local:ToggleBoolPropertyAction TargetName="TestCheckBox" PropertyName="IsChecked" /> </i:EventTrigger> <i:EventTrigger EventName="MouseEnter"> <local:ToggleBoolPropertyAction TargetName="TestCheckButton" PropertyName="IsEnabled" /> </i:EventTrigger> <i:EventTrigger EventName="MouseLeave"> <local:ToggleBoolPropertyAction TargetName="TestCheckButton" PropertyName="IsEnabled" /> </i:EventTrigger> </i:Interaction.Triggers> </Rectangle> </StackPanel> </Grid> </Window>
マウスがRectangleの外の場合:
マウスがRectangleの中の場合:
TargetedTriggerAction.Invokeの部分をいじればいろんなプロパティを変更できます(していいのか?)。