2012-08-15 71 views
4

最近我有機會玩Windows 8發佈預覽(Build 8400具體)。我的目標是僅在Windows 8下調查出現在我們的產品(WPF應用程序)中的錯誤。這些錯誤看起來非常簡單 - 幾個按鈕在不應該時被禁用。它看起來很容易修復,但我決定找到根本原因。Windows 8上的命令綁定問題(發佈預覽版)

事實證明,當綁定到命令的控件收到CanExecuteChanged通知時,如果發件人不是相同的命令,它不會請求命令的CanExecute方法。在命令對模型執行一些操作並且執行能力取決於模型狀態的情況下,這是一個問題。例如,假設你有一個模型:

class MyModel 
    { 
    public void ChangeModel(bool makeValidForCommand) 
    { 
     Valid = makeValidForCommand; 

     if (ModelChanged != null) 
     ModelChanged(this, new EventArgs()); 
    } 

    public bool Valid { get; private set; } 

    public event EventHandler ModelChanged; 
    } 

和命令:

class MyCommand : ICommand 
    { 
    public MyCommand(MyModel model) 
    { 
     _model = model; 
    } 

    public bool CanExecute(object parameter) 
    { 
     return _model.Valid; 
    } 

    public event EventHandler CanExecuteChanged 
    { 
     add { _model.ModelChanged += value; } 
     remove { _model.ModelChanged -= value; } 
    } 

    public void Execute(object parameter) { } 

    private MyModel _model; 
    } 

不幸的是,這不會在Windows 8工作 - 綁定到命令按鈕將保持禁用不當(或在模型改變狀態之後。它雖然在Windows 7上運行得非常好!

的命令可以寫成這樣:

class MyCommand : ICommand 
    { 
    public MyCommand(MyModel model) 
    { 
     _model = model; 
    } 

    public bool CanExecute(object parameter) 
    { 
     return _model.Valid; 
    } 

    public event EventHandler CanExecuteChanged 
    { 
     add 
     { 
     _canExecuteChanged += value; 
     _model.ModelChanged -= _modelChanged; 
     _model.ModelChanged += _modelChanged; 
     } 

     remove 
     { 
     _canExecuteChanged -= value; 
     _model.ModelChanged -= _modelChanged; 
     } 
    } 

    public void Execute(object parameter) 
    { 
    } 

    private void _modelChanged(object sender, EventArgs e) 
    { 
     if (_canExecuteChanged != null) 
     _canExecuteChanged(this, new EventArgs()); 
    } 

    private event EventHandler _canExecuteChanged; 
    private MyModel _model; 
    } 

現在發件人是命令本身,一切都很好。另一種選擇是使用CommandManager及其RequerySuggested事件:

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

又一次它的作品!嗯,現在我完全不解。發件人不是命令 - 它是空的,但如果我嘗試發送我自己的事件與null發件人它不再工作。

有沒有人遇到過相同的問題?在新的Windows上進行優化是否是一種奇怪的方式?老實說,它看起來更像是一個錯誤。

+1

這是奇怪... WPF是在.NET框架中實現,而不是在Windows中,所以它不應該不管你正在使用的Windows版本。您在Windows 8上使用了哪個版本的.NET? – 2012-08-15 15:09:57

+0

確實,但我認爲框架中存在與系統相關的部分,在Win7和Win8上顯然不同。我構建了我的4.0版應用程序。 – Maxym 2012-08-15 15:40:08

+0

令人驚訝的是,我將目標框架版本從4.0更改爲3.5,該錯誤消失了。 – Maxym 2012-08-15 15:43:21

回答

4

似乎,這是.Net Framework 4.5中的重大變化。 問題報告給微軟在這裏:

http://connect.microsoft.com/VisualStudio/feedback/details/751429/wpf-icommand-canexecutechanged-behaviour-change-in-net-4-5

+0

這也打擊了我,花了相當長的時間,直到我終於弄清楚爲什麼我的應用程序不能在安裝了.net 4.5的系統上工作。經過大量的調試和搜索後,我發現這讓我可以修復它。我正在使用使用null作爲發件人的RelayCommand。 – 2012-11-23 09:43:25