代码之家  ›  专栏  ›  技术社区  ›  stakx - no longer contributing Saravana Kumar

Windows窗体中的“易失性”数据绑定可能吗?

  •  1
  • stakx - no longer contributing Saravana Kumar  · 技术社区  · 14 年前

    假设我正在实现一个Winforms UI,其中所有命令都遵循以下模式:

    interface ICommand
    {
        bool CanExecute { get; }
        void Execute();
    }
    

    触发此类命令的按钮或菜单项应具有以下设置:

    • 财产 Enabled CanExecute
    • Click 链接到命令的 Execute

    这个 麻烦 CanExecute公司 是,实施 INotifyPropertyChanged 因为它在这里不起作用,因为这个属性不能直接修改,而是依赖于程序中不需要与命令相关的其他因素。一个人不应该触发命令的 PropertyChanged

    如何让数据绑定管理器知道 CanExecute公司

    下面是一个(纯粹虚构的)我的问题的例子:

    bool CanExecute
    {
        get
        {
            return User.LoggedInForAtLeastNMinutes(5);
            // how would you trigger data-binding updates for CanExecute? 
        }
    }
    

    CanExecute公司 (好像它是一个易失性字段),但这不是Winforms数据绑定的工作方式。有人能解决这个问题吗?


    5 回复  |  直到 14 年前
        1
  •  2
  •   Tim Robinson    14 年前

    我将实施 INotifyPropertyChanged 不管(或添加 CanExecuteChanged 事件,具有相同的效果)。我会努力让对象知道何时在正确的时间引发属性更改事件,而不是轮询。

    例如,在你虚构的例子中,你可以有一个 UserLoggedIn 事件。作为回应,你可以设置一个5分钟的计时器;当计时器结束时,引发property changed事件。

    • 轮询过于频繁,应用程序会消耗CPU来检查不可能发生的事件(例如,每10秒轮询一次以查看是否有5分钟已结束)
    • 没有足够频繁地进行轮询,而控件 CanExecute 属性滞后于UI的其余部分(例如,在进行文本选择和 CopyTextCommand.CanExecute 属性更新)

    that taken by Microsoft Foundation Classes 在C++中,它是在任何时候应用程序的消息循环空闲的。当您知道只有用户界面交互才能影响您的 CanExecute公司

        2
  •  1
  •   stakx - no longer contributing Saravana Kumar    14 年前

    使用 Timer 不断地调查 CanExecute 财产。提高 PropertyChanged 属性更改时的事件。

        3
  •  0
  •   Sebastian Piu    14 年前

    下面是我当前的“CommandManager”实现的摘录;

     public CommandManager()
        {
            Commands = new List<ICommand>();
    
            Binders = new List<ICommandBinder>
                          {
                              new ControlBinder(),
                              new MenuItemCommandBinder()
                          };
    
            Application.Idle += UpdateCommandState;
        }
     private void UpdateCommandState(object sender, EventArgs e)
        {
            Commands.Do(c => c.Enabled);
        }
    

    (Do()只是一个执行foreach的扩展方法,与linq Select()类似,但它执行的是操作而不是Func)

    http://codewithpassion.blogspot.com/2010/11/icommand-and-commandmanager-for-windows.html