最近我有機會玩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上進行優化是否是一種奇怪的方式?老實說,它看起來更像是一個錯誤。
這是奇怪... WPF是在.NET框架中實現,而不是在Windows中,所以它不應該不管你正在使用的Windows版本。您在Windows 8上使用了哪個版本的.NET? – 2012-08-15 15:09:57
確實,但我認爲框架中存在與系統相關的部分,在Win7和Win8上顯然不同。我構建了我的4.0版應用程序。 – Maxym 2012-08-15 15:40:08
令人驚訝的是,我將目標框架版本從4.0更改爲3.5,該錯誤消失了。 – Maxym 2012-08-15 15:43:21