參考
- https://devbox.cn/p/WPFCommandParame_71b81418.html
環境
軟體/系統 | 版本 | 說明 |
---|---|---|
Windows | Windows 10 專業版 22H2 19045.4046 | |
Microsoft Visual Studio | Microsoft Visual Studio Community 2022 (64 位) - 17.6.5 | |
Microsoft .Net SDK | 8.0.101 | 手動安裝 |
Microsoft .Net SDK | 7.0.306 | Microsoft Visual Studio 攜帶 |
.net | 6.x | 建立當前文章演示 WPF 專案時指定 .net 版本所選擇的框架 |
Prism Template Pack | 2.4.1 | Microsoft Visual Studio 擴充套件 |
XAML Style for Visual Studio 2022 | 3.2311.2 | Microsoft Visual Studio 擴充套件(XAML 自動格式化) |
HandyControl | 3.5.1 | NuGet包 |
Prism.DryIoc | 8.1.97 | NuGet包 |
提示
本文使用到了 Prism ,但是未使用該框架也可以用本方法解決。
正文
問題
在 ViewModel 中定義了 bool Listening
,在 XAML CommandParameter 中進行繫結,當 Listening
值更新時,CommandParameter 接收的 Listening
不更新。
解決
- 當使用 Prism 框架時,視窗的 MVVM 需要繼承 BindableBase,並且引數更新時呼叫 SetProperty 方法(通知 UI 引數進行了更新)。
// 以 MainWindow 視窗與 Listening 引數舉例
using FileMonitoring.Commands;
using FileMonitoring.Views;
using Prism.Mvvm;
using System.ComponentModel;
using System.Data.Common;
using System.Windows;
using System.Windows.Input;
using System.Xml.Linq;
namespace FileMonitoring.ViewModels
{
public class MainWindowViewModel : BindableBase
{
private bool _listening = false;
public bool Listening
{
get { return _listening; }
set {
SetProperty(ref _listening, value);
}
}
}
}
- 命令介面繼承
ICommand
時實現了public event EventHandler CanExecuteChanged;
,需要調整為如下程式碼才可以重新觸發 CanExecute 事件 :
public event EventHandler CanExecuteChanged {
add{CommandManager.RequerySuggested += value;}
remove{CommandManager.RequerySuggested -= value;}
}
完整命令介面 ICommand
實現為:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using static ImTools.ImMap;
namespace FileMonitoring.Commands
{
/**
* 開啟監聽命令
*/
internal class OnStartListenCommand : ICommand
{
private Action<object?> _execute;
public OnStartListenCommand(Action<object?> execute)
{
_execute = execute;
}
public event EventHandler CanExecuteChanged {
add{CommandManager.RequerySuggested += value;}
remove{CommandManager.RequerySuggested -= value;}
}
public bool CanExecute(object parameter)
{
return !(parameter as bool?) ?? false;
}
public void Execute(object parameter)
{
Trace.WriteLine("開啟監聽命令");
_execute(parameter);
}
}
}