When writing Command="{Binding WalterlvCommand}"
into your XAML code and your button or other controls can automatically execute command and updating the command states, such as enabling or disabling the button.
We’ll talk about when the UI commands will refresh their can-execute states and how to force updating the states.
This post is written in multiple languages. Please select yours:
中文 English
This post is written for my Stack Overflow answer:
- Why C# WPF button binding command won’t change view after using simple injector? - Stack Overflow
A simple sample
1 | <Button x:Name="TestCommand" Command="{Binding WalterlvCommand}" /> |
---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public class Walterlv { // Assume that I've initialized this command. public WalterlvCommand WalterlvCommand { get; } } public class WalterlvCommand : ICommand { public bool SomeFlag { get; set; } bool ICommand.CanExecute(object parameter) { // Return the real can execution state. return SomeFlag; } void ICommand.Execute(object parameter) { // The actual executing procedure. } } |
---|
See this code below. After 5 seconds, the button will still be disabled even that we set the SomeFlat
to true
.
1 2 3 4 5 | var walterlv = new Walterlv(); TestCommand.DataContext = walterlv; await Task.Delay(5000); walterlv.WalterlvCommand.SomeFlag = true; |
---|
How to update manually?
Call this method after you want to update your command states if it won’t update:
1 | CommandManager.InvalidateRequerySuggested(); |
---|
When do the commands update their states?
Commands only update when these general events happen:
KeyUp
MouseUp
GotKeyboardFocus
LostKeyboardFocus
You can see the code here:
- CommandDevice.PostProcessInput
And the key code is here:
1 2 3 4 5 6 7 | if (e.StagingItem.Input.RoutedEvent == Keyboard.KeyUpEvent || e.StagingItem.Input.RoutedEvent == Mouse.MouseUpEvent || e.StagingItem.Input.RoutedEvent == Keyboard.GotKeyboardFocusEvent || e.StagingItem.Input.RoutedEvent == Keyboard.LostKeyboardFocusEvent) { CommandManager.InvalidateRequerySuggested(); } |
---|
Actually, not only those events above but also these methods below refresh the command states:
- When opening a submenu of a MenuItem. See MenuItem.OnIsSubmenuOpenChanged
- When pressing and holding a RepeatButton in a Tracker. Tracker.DecreaseRepeatButton
- When change the readonly property of
DataGridCell
. DataGridCell.OnNotifyIsReadOnlyChanged - When doing many operations in a
DataGrid
. DataGrid - When navigating back in a
JournalNavigationScope
. JournalNavigationScope.OnBackForwardStateChange - And others, you can find references of
InvalidateRequerySuggested
: InvalidateRequerySuggested
本文会经常更新,请阅读原文: https://blog.walterlv.com/post/when-wpf-commands-update-their-states-en.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected]) 。