Silverlight 4 Commands–Enable/Disable Button
Úvod
V dnešním článku si ukážeme jak svázat tlačítko s Commandem a jak tomuto Commandu přidat nějakou podmínku, za které ho lze spustit či nikoliv. Pokud nebude splněna podmínka, tlačítko bude “disable”, jinak “enable”.
Command
Běžně jste zvyklí, že když někdo klikne na tlačítko, vyvolá se událost Click. V Silverlightu (I ve WPF) pokud nastavíme tlačítku Command, tak po stisku tlačíka se nevyvolá událost Click, ale nýbrž náš Command. “Náš Command” je třída implementující interface ICommand, který nabízí několik metod:
public interface ICommand { bool CanExecute(object parameter); void Execute(object parameter); event System.EventHandler CanExecuteChanged; }
Vytvoříme si tedy třídu, implementující zmiňovaný interface. Třída obsahuje pouhé dvě vlastnosti: akci, která se má vykonat a podmínku, za jaké je povoleno tuto akci vykonat.
public class RelayCommand : ICommand { #region Fields private readonly Action< object > _execute; private readonly Predicate< object > _canExecute; #endregion // Fields #region Constructors public RelayCommand(Action<object> execute, Predicate<object> canExecute = null) { if ( execute == null ) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } #endregion // Constructors #region ICommand Members [DebuggerStepThrough] public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute(parameter); } public void Execute(object parameter) { _execute(parameter); } #endregion // ICommand Members public event EventHandler CanExecuteChanged; }
Nyní si už vytvoříme pouze náš ViewModel, ve kterém definujeme náš Command a potřebnou logiku, která bude rozhodovat o tom, zda se může či nemůže command vykonat. ViewModel je velice jednoduchý, máme zde pouze vlastnost FirstName, která když nabyde hodnoty “Test”, tak se tlačítko povolí a my budeme moct provést fiktivní uložení.
public class MainPageViewModel : ViewModelBase { private string _firstName; private ICommand _saveCommand; public string FirstName { get { return _firstName; } set { _firstName = value; OnPropertyChanged("FirstName"); } } public ICommand SaveCommand { get { if ( _saveCommand == null ) _saveCommand = new RelayCommand(param => Save(), condition => IsValid); return _saveCommand; } } void Save() { MessageBox.Show("Saved"); } public bool IsValid { get { // vlastnost, ktera vrati true nebo false podle toho zda jsou // vyplnene data ve formulari validni if ( string.IsNullOrEmpty(FirstName) ) return false; return FirstName == "Test"; } } }
Ještě než spustíme aplikace, tak Vám zde ukážu implementaci třídy ViewModelBase a MainPage.xaml.
ViewModelBase
public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable { #region | Constructor protected ViewModelBase() { } #endregion // Constructor #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = this.PropertyChanged; if ( handler != null ) { var args = new PropertyChangedEventArgs(propertyName); handler(this, args); } } #endregion // INotifyPropertyChanged Members #region IDisposable Members public void Dispose() { this.OnDispose(); } protected virtual void OnDispose() { } #endregion // IDisposable Members }
MainPage.xaml
<StackPanel x:Name="LayoutRoot" Background="White"> <TextBox Text="{Binding FirstName, Mode=TwoWay}"/> <Button Content="Save" Command="{Binding SaveCommand}"/> </StackPanel>
MainPage.xaml.cs
public MainPage() { InitializeComponent(); this.DataContext = new MainPageViewModel(); }
Nyní když aplikaci spustíte, napíšete do textového pole Test a stisknete Tab (aby textbox ztratil focus), tak uvidíte, že se nic nestane a tlačítko zůstane zakázané (nelze na něho kliknout). Co je špatně?
Auto Enable/Disable Button
Aby jsme povolili automatické povolení tlačítka, v případě platné podmínky, je potřeba ve vhodný okamžik vyvolat událost CanExecuteChanged, která ověří naší podmínku a v případě, že je podmínka validní, se tlačítko povolí.Pro srovnání WPF obsahuje třídu CommandManager, která I když uživatel pouze přejíždí myší po UI, tak automaticky vyvolává tuto událost, Silverlight nikoliv!.
Provedeme menší úpravy v našem kódu:
Vytvoříme nový interface nazvaný IRelayCommand
public interface IRelayCommand : ICommand { void RaiseCanExecuteChanged(); }
Zaměníme class RelayCommand : ICommand za class RelayCommand : IRelayCommand a v MainPageViewModel bude SaveCommand typu IRelayCommand.
Na závěr už jenom upravíme setter vlastnosti FirstName, že po volání OnPropertyChanged(“FirstName”) zavoláme
SaveCommand.RaiseCanExecuteChanged();
čímž se provede otestování vlastnosti IsValid, která v případě, že FirstName obsahuje slovo Test vrátí True a tlačítko bude povolené.
Komentáře