WPF MVVM command canexecute enable/disable button

2020-02-01 04:28发布

I want to enable RibbonButton when textbox property text isn't null. Disable RibbonButton when textbox property text is null. I want to use CanExecute method in ICommand for it. How can I do it?

View:

 <Custom:RibbonButton
                        LargeImageSource="..\Shared\img\save_diskete.png"
                        Label="Save"
                        Command="{Binding ButtonCommand}">
                    </Custom:RibbonButton>

ViewModel

class KomentarViewModel:BaseViewModel
    {
        #region Data
        private ICommand m_ButtonCommand;
        public ICommand ButtonCommand
        {
            get
            {
                return m_ButtonCommand;
            }
            set
            {
                m_ButtonCommand = value;
            }
        }
        private string textKomentar;
        public string TextKomentar
        {
            get
            {
                return this.textKomentar;
            }
            set
            {
                // Implement with property changed handling for INotifyPropertyChanged
                if (!string.Equals(this.textKomentar, value))
                {
                    textKomentar = value;
                    OnPropertyChanged("TextKomentar");
                }
            }
        }        
        private ObservableCollection<Komentar> allCommentsInc;
        public ObservableCollection<Komentar> AllCommentsInc
        {
            get
            {
                return allCommentsInc;
            }
            set
            {
                allCommentsInc = value;
                OnPropertyChanged("AllCommentsInc");
            }
        }

        public int idIncident { get; private set; }
        public Incident incident { get; private set; }
        #endregion

        #region Constructor
        public KomentarViewModel(int id)
        {
            CC_RK2Entities context = new CC_RK2Entities();
            this.idIncident = id;

            AllCommentsInc = new ObservableCollection<Komentar>(context.Komentar.Where(a => a.Incident_id == idIncident));
            incident = context.Incident.Where(a => a.id == idIncident).First();

            //ButtonCommand = new RelayCommand(new Action<object>(ShowMessage));
        }
        #endregion        

        #region Methods
        //ukaz napsany text
        public void ShowMessage(object obj)
        {
            //MessageBox.Show(obj.ToString());
            MessageBox.Show(this.TextKomentar);
        }
}

RelayCommand

namespace Admin.Shared.Commands
{
    class RelayCommand : ICommand
    {
        private Action<object> _action;

        public RelayCommand(Action<object> action)
        {
            _action = action;
        }

        #region ICommand Members

        public bool CanExecute(object parameter)
        {
            return true;            
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
                _action(parameter);
        }

        #endregion
    }
}

标签: c# wpf mvvm
3条回答
男人必须洒脱
2楼-- · 2020-02-01 04:48

You need to modify your RelayCommand class like this

  class RelayCommand : ICommand
{
    private Action<object> _action;
    private Func<bool> _func;  

    public RelayCommand(Action<object> action,Func<bool> func)
    {
        _action = action;
        _func = func;
    }

    public void RaiseCanExecuteChanged()
    {
        if(CanExecuteChanged!=null)
            CanExecuteChanged(this,new EventArgs());
    }

    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        if (_func != null)
           return _func();
        return true;
    }



    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _action(parameter);
    }

    #endregion
}

Initialize ButtonCommand as

ButtonCommand = new RelayCommand((s) => ShowMessage(s),()=>!string.IsNullOrEmpty(TextKomentar));

RaiseCanExcuteChanged from the setter of Text property

        public string TextKomentar
    {
        get
        {
            return this.textKomentar;
        }
        set
        {
            // Implement with property changed handling for INotifyPropertyChanged
            if (!string.Equals(this.textKomentar, value))
            {
                textKomentar = value;
                OnPropertyChanged("TextKomentar");
            }
            ButtonCommand.RaiseCanExecuteChanged();
        }
    }
查看更多
狗以群分
3楼-- · 2020-02-01 05:00

implement this for canexecute:

public bool CanExecute(object parameter)
        {if(thistext available)
            return true; 
         else
            return false;  
        }

Since, CanExecuteChanged is raised when the CanExecute method of an ICommand gets changed. it gets invoked when some command that could change canexecute. and can execute changed should be changed to this:

public event EventHandler CanExecuteChanged {
    add {
        CommandManager.RequerySuggested += value;
    }
    remove {
        CommandManager.RequerySuggested -= value;
    }
}

EDIT

in your view model constructor:

m_ButtonCommand= new RelayCommand(Submit, CanSubmit);

now method for this submit:
 private bool CanSubmit(object obj)
        {
            if(thistext available)
                return true; 
             else
                return false;  

        }
 public void Submit(object _)
  {//... code}

 public event EventHandler CanExecuteChanged {
        add {
            CommandManager.RequerySuggested += value;
        }
        remove {
            CommandManager.RequerySuggested -= value;
        }
    }

do it like this.

查看更多
劳资没心,怎么记你
4楼-- · 2020-02-01 05:11

Last time I used Microsoft.Practices.Prism.Commands namesapce from Microsoft.Practices.Prism.dll. Class DelegateCommand has own RaiseCanExecuteChanged() method. So the benifit is you don't have to write yout own implementation of ICommand.

XAML:

<StackPanel>
    <CheckBox IsChecked="{Binding IsCanDoExportChecked}" />
    <Button Command="{Binding ExportCommand}" Content="Export" />
</StackPanel>

ViewModel:

public class ViewModel
{
    public DelegateCommand ExportCommand { get; }

    public ViewModel()
    {
        ExportCommand = new DelegateCommand(Export, CanDoExptor);
    }

    private void Export()
    {
        //logic
    }

    private bool _isCanDoExportChecked;

    public bool IsCanDoExportChecked
    {
        get { return _isCanDoExportChecked; }
        set
        {
            if (_isCanDoExportChecked == value) return;

            _isCanDoExportChecked = value;
            ExportCommand.RaiseCanExecuteChanged();
        }
    }

    private bool CanDoExptor()
    {
        return IsCanDoExportChecked;
    }
}
查看更多
登录 后发表回答