locked
CommandBindings クラスを作成し、コマンドをバインドしてIsEnabled を管理したい RRS feed

  • 質問

  • コマンドをバインドして、onPropatyChange から拾いボタンの IsEnabled を一括更新したいのですが、
    コマンドをバインドできません。コードが長いのですが、アドバイスを願えたらとおもいます。

    IsEnabled については設定ができますが、クリック時にイベントを拾いません。

    画面は単純なログイン画面です。

     <Grid x:Name="LayoutRoot" Height="160" Width="202">
    
     <Button Content="Login" Name="button_login" />
    
     <TextBox Text="{Binding Path=User_name,ValidatesOnDataErrors=True,Mode=TwoWay}" Name="user_name" />
    
     <PasswordBox Password="{Binding Path=User_pass,ValidatesOnDataErrors=True,Mode=TwoWay}" Name="user_pass" />
    
     </Grid>
    
    
    //Login.xaml.cs
    
    
    
     public partial class Login : UserControl
    
     {
    
    
    
     private LoginLogic _loginlogic;
    
     private CommandBindings _commandBindings;
    
     public Login()
    
     {
    
     InitializeComponent();
    
     InitializeLoginLogic();
    
     _commandBindings = new CommandBindings();
    
      _commandBindings.AddCommand(button_login,_loginlogic.LoginCommand);
    
    

    this.KeyDown += new KeyEventHandler(Page_keyDown); CtlsTabList = new Contoltab_center(LayoutRoot); }  private void InitializeLoginLogic() { _loginlogic = new LoginLogic(); _loginlogic.NaviTargetPage = this; _loginlogic.PropertyChanged +=new System.ComponentModel.PropertyChangedEventHandler(_logic_PropertyChanged); //バインド元オブジェクトを設定 this.DataContext = _loginlogic; } void _logic_PropertyChanged(object sender, PropertyChangedEventArgs e) { _commandBindings.RefreshControlEnabled();//ここでボタンの状態を一括設定 } }

     

    //LoginLogic.cs<br/><br/><br/>public class LoginLogic:ModelBase
    
    {
    
    //Data Property user_pass も同様なので省略
    
    
    
     private string _user_name;
     [Required(ErrorMessage = "IDを入力してください")]  public string User_name { get { return _user_name; } set {   _user_name = value;    UpdateErrors("User_name", value);   OnPropertyChanged("User_name"); } }
    // Command Property private DelegateCommand _loginCommand; public DelegateCommand LoginCommand { get { if (_loginCommand == null) { _loginCommand = new DelegateCommand(ExecuteLoginCommand, CanExecuteUpdateCommand); } return _loginCommand; } } private bool CanExecuteUpdateCommand() { if ((User_name == "") || (User_pass == "") || (User_name == null) || (User_pass == null)) { return false; //ログインボタンを押せなくする }else { return true; } } }

     

    // CommandBindings.cs
    
    
    
     public class CommandBindings
    
     {
    
     private List<Action> _resetEnabledActions;
    
    
    
     public CommandBindings()
    
     {
    
     _resetEnabledActions = new List<Action>();
    
     }
    
    
    
     public void AddCommand(dynamic control, DelegateCommand command)
    
     {
    
     Action a = () => control.IsEnabled = command.CanExecute(null);
    
     _resetEnabledActions.Add(a);
    
     Binding b = new Binding();
    
     b.Path = new PropertyPath(command);
    
     b.NotifyOnValidationError = true;
    
     b.ValidatesOnDataErrors = true;
    
     b.ValidatesOnExceptions = true;
    
     b.ValidatesOnNotifyDataErrors = true;
    
     control.SetBinding(Button.CommandProperty, b);  //ここで、コマンドを追加しているつもりですが、動作しない
    
     }
    
     public void RefreshControlEnabled()
    
     {
     foreach (Action x in _resetEnabledActions)
    
     {
    
       x();
    
     }
    
     }
    
    
    
     }
    
    

     どうか、よろしくお願いします。

     




    • 編集済み Michi.K 2011年5月18日 8:17 コードの修正
    2011年5月18日 6:49

回答

  • 自己解決しました。

    CommandBindings.cs を CommandEnableds.cs に変更してコマンドをバインドしないようにしました。

      public class CommandEnableds
      {
        private List<Action> _resetEnabledActions;
    
        public CommandEnableds()
        {
          _resetEnabledActions = new List<Action>();
        }
    
        public void AddCommand(Control control, DelegateCommand command)
        {
          Action a = () => control.IsEnabled = command.CanExecute();
          _resetEnabledActions.Add(a);
        }
    
        public void RefreshControlEnabled()
        {
          foreach (Action x in _resetEnabledActions)
          {
            x();
          }
        }
      }
    

    として、コードビハインド側で

    private CommandEnableds _CommandEnableds;
    
    _CommandEnableds = new CommandEnableds();
    _CommandEnableds.AddCommand(button_login, _loginlogic.LoginCommand);
    
    
    _loginlogic = new LoginLogic();
    _loginlogic.PropertyChanged +=new System.ComponentModel.PropertyChangedEventHandler(_logic_PropertyChanged);
    
    this.DataContext = _loginlogic;
    
    EventHandler handler = (s, e) => _loginlogic.LoginCommand.Execute();
    this.button_login.Click += new RoutedEventHandler(handler);
    
    これで、条件一致でボタンの IsEnabled を操作しつつ イベントにコマンドが割り当てられました。
    お騒がせしました。
    • 回答としてマーク Michi.K 2011年5月20日 1:38
    2011年5月20日 1:37

すべての返信

  •     public void AddCommand(dynamic control, DelegateCommand command)
        {
    
          Action a = () => control.IsEnabled = command.CanExecute(null);
    
          _resetEnabledActions.Add(a);
    
          EventHandler handler = (s, e) => command.Execute(null);
          control.MouseEnter += new MouseEventHandler(handler);
        }
    
    こうすると、マウスがボタンの上にくると実行される。が、IsEnabled プロパティは無視されてしまいます。
    2011年5月18日 8:20
  • 自己解決しました。

    CommandBindings.cs を CommandEnableds.cs に変更してコマンドをバインドしないようにしました。

      public class CommandEnableds
      {
        private List<Action> _resetEnabledActions;
    
        public CommandEnableds()
        {
          _resetEnabledActions = new List<Action>();
        }
    
        public void AddCommand(Control control, DelegateCommand command)
        {
          Action a = () => control.IsEnabled = command.CanExecute();
          _resetEnabledActions.Add(a);
        }
    
        public void RefreshControlEnabled()
        {
          foreach (Action x in _resetEnabledActions)
          {
            x();
          }
        }
      }
    

    として、コードビハインド側で

    private CommandEnableds _CommandEnableds;
    
    _CommandEnableds = new CommandEnableds();
    _CommandEnableds.AddCommand(button_login, _loginlogic.LoginCommand);
    
    
    _loginlogic = new LoginLogic();
    _loginlogic.PropertyChanged +=new System.ComponentModel.PropertyChangedEventHandler(_logic_PropertyChanged);
    
    this.DataContext = _loginlogic;
    
    EventHandler handler = (s, e) => _loginlogic.LoginCommand.Execute();
    this.button_login.Click += new RoutedEventHandler(handler);
    
    これで、条件一致でボタンの IsEnabled を操作しつつ イベントにコマンドが割り当てられました。
    お騒がせしました。
    • 回答としてマーク Michi.K 2011年5月20日 1:38
    2011年5月20日 1:37