بررسی اینترفیس ICommand در WPF
نویسنده: مهدی ملائیان
تاریخ: ۱۳۹۴/۱۰/۲۶ ۱۹:۱۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
| نام عضو | توضیحات |
| Bool CanExecute(object parameter) | این تابع پارامتری از نوع object را دریافت میکند و یک مقدار bool را به خروجی تابع میفرستد. اگر مقدار خروجی متد، true باشدcommand اجرا خواهد شد و در غیر اینصورت اتفاقی رخ نخواهد داد. اغلب ازDelegate ها به عنوان پارامتر این تابع استفاده میشود؛Delegate های پیش ساختهای همچون Action,Predicate,Func |
| Event EventHandler CanExecuteChanged | این رویداد برای آگاه سازی UI که به Command متصل است، استفاده میشود .بر اساس خروجی تابع CanExecute، این رویداد اتفاق میافتد. |
| Void Execute(Object parameter) | این متد کار اصلی را در Commandها انجام میدهد. این متد تنها زمانی اجرا میشود که متدCanExecute مقدار true را بازگرداند. این تابع پارامتری را از نوع object دریافت میکند، اما عموما ما یکDelegate را به آن ارسال میکنیم. Delegate ارجاعی را به متدی، در خود نگاه میدارد که انتظار داریم در صورت اجرایcommand ، اجرا شود. |
<Grid DataContext="{Binding Source={StaticResource calculatorVM}}" Background="#FFCCCC">
<Grid.RowDefinitions>
<RowDefinition Height="80"/>
<RowDefinition/>
<RowDefinition Height="80"/>
<RowDefinition Height="44"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" FontSize="25"
VerticalAlignment="Top" HorizontalAlignment="Center" Foreground="Blue" Content="ICommand Sample"/>
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
Margin="10,0,0,0" VerticalAlignment="Bottom" FontSize="20" Content="First Input"/>
<Label Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="2"
Margin="10,0,0,0" VerticalAlignment="Bottom" FontSize="20" Content="Second Input"/>
<TextBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="10,0,0,0" FontSize="20"
HorizontalAlignment="Left" Height="30" Width="150" TextAlignment="Center" Text="{Binding FirstValue, Mode=TwoWay}"/>
<TextBox Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2" Margin="10,0,0,0" FontSize="20"
HorizontalAlignment="Left" Height="30" Width="150" TextAlignment="Center" Text="{Binding SecondValue, Mode=TwoWay}"/>
<Rectangle Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="4" Fill="LightBlue"/>
<Button Grid.Row="2" Grid.Column="0" Content="+" Margin="10,0,0,0" HorizontalAlignment="Left" Height="50" Width="50" FontSize="30" Command="{Binding AddCommand}"/>
<Label Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" FontSize="25" Margin="10,0,0,0" HorizontalAlignment="Left" Height="50" Content="Result : "/>
<TextBlock Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="2" FontSize="20" Margin="10,0,0,0" Background="BlanchedAlmond"
TextAlignment="Center" HorizontalAlignment="Left" Height="36" Width="150" Text="{Binding Output}"/>
</Grid> xmlns:myview="clr-namespace:ICommnadSample.Views"
<Grid>
<myview:CalculatorView/>
</Grid> private double firstValue;
private double secondValue;
private double output;
public double FirstValue
{
get { return firstValue; }
set
{
firstValue = value;
OnPropertyChanged("FirstValue");
}
}
public double SecondValue
{
get { return secondValue; }
set
{
secondValue = value;
OnPropertyChanged("SecondValue");
}
}
public double Output
{
get { return output; }
set
{
output = value;
OnPropertyChanged("Output");
}
} public class PlusCommand : ICommand
{
private CalculatorViewModel calculatorViewModel;
public PlusCommand(CalculatorViewModel vm)
{
calculatorViewModel = vm;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
calculatorViewModel.Add();
}
public event EventHandler CanExecuteChanged;
} private PlusCommand plusCommand;
public CalculatorViewModel()
{
plusCommand = new PlusCommand(this);
} xmlns:vm="clr-namespace:ICommnadSample.ViewModels"
<UserControl.Resources>
<vm:CalculatorViewModel x:Key="calculatorVM" />
</UserControl.Resources> public void Add()
{
Output = firstValue + secondValue;
} public ICommand AddCommand {
get
{
return plusCommand;
}
} Command="{Binding AddCommand}" public class ViewModelBase:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
} public class CalculatorViewModel : ViewModelBase
OnPropertyChanged("FirstValue"); public class CalculatorViewModel : ViewModelBase
{
private double firstValue;
private double secondValue;
private double output;
private PlusCommand plusCommand;
public CalculatorViewModel()
{
plusCommand = new PlusCommand(this);
}
public double FirstValue
{
get { return firstValue; }
set
{
firstValue = value;
OnPropertyChanged("FirstValue");
}
}
public double SecondValue
{
get { return secondValue; }
set
{
secondValue = value;
OnPropertyChanged("SecondValue");
}
}
public double Output
{
get { return output; }
set
{
output = value;
OnPropertyChanged("Output");
}
}
public ICommand AddCommand
{
get
{
return plusCommand;
}
}
internal void Add()
{
Output = firstValue + secondValue;
}
}
حال میتوانید برنامه را اجرا و تست کنید:
برای درک بهتر عملیات انقیاد دادها میتوانید به این مقاله مراجعه کنید.
using System;
using System.Windows.Input;
namespace Common.Mvvm
{
public class DelegateCommand<T> : ICommand
{
readonly Func<T, bool> _canExecute;
readonly Action<T> _executeAction;
public DelegateCommand(Action<T> executeAction, Func<T, bool> canExecute = null)
{
if (executeAction == null)
throw new ArgumentNullException("executeAction");
_executeAction = executeAction;
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add { if (_canExecute != null) CommandManager.RequerySuggested += value; }
remove { if (_canExecute != null) CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute((T)parameter);
}
public void Execute(object parameter)
{
_executeAction((T)parameter);
}
}
} public DelegateCommand<object> DoCopyAllLines { set; get; } DoCopyAllLines = new DelegateCommand<object>(CopyAllLines, info => true);
private void CopyAllLines(object data)
{
// ...
}