更新:根据反馈重新设计。
由于 UI 需要 CanExecute() 返回 false 的原因,我想到了两件事:
选项 1:将可枚举消息属性添加到命令接口,并在调用 CanExecute() 期间根据需要填充它。然后 UI 可以根据需要询问该属性。如果你走这条路,请确保每次调用 CanExecute() 时清除属性的内容,以免丢失状态。
public interface ICommand
{
IEnumerable<string> Messages { get; }
bool CanExecute();
void Execute();
}
public class SomeCommand : ICommand
{
public IEnumerable<string> Messages { get; private set; }
public bool CanExecute()
{
var messages = new List<string>();
var canExecute = true;
if (SomeCondition)
{
canExecute = false;
messages.Add("Some reason");
}
if (AnotherCondition)
{
canExecute = false;
messages.Add("Another reason");
}
Messages = messages;
return canExecute;
}
public void Execute() { }
}
选项 2: 让 CanExecute() 返回一个包含布尔值以及可枚举消息属性的对象。这表明消息仅适用于 CanExecute() 的调用。但是,根据您实施的位置/方式(例如数据绑定),这可能会使其他场景变得比您想要的更复杂。
public class CanExecuteResult
{
public bool CanExecute { get; set; }
public IEnumerable<string> Messages { get; set; }
}
public interface ICommand
{
CanExecuteResult CanExecute();
void Execute();
}
public class SomeCommand : ICommand
{
public CanExecuteResult CanExecute()
{
var result = new CanExecuteResult { CanExecute = true };
var messages = new List<string>();
if (SomeCondition)
{
result.CanExecute = false;
messages.Add("Some reason");
}
if (AnotherCondition)
{
result.CanExecute = false;
messages.Add("Another reason");
}
result.Messages = messages;
return result;
}
public void Execute() { }
}
显然,您希望如何处理接口、可枚举类型等的细节取决于您。代码只是这个想法的代表。