gpt4 book ai didi

c# - Relaycommand ICommand.CanExecute 不触发

转载 作者:太空宇宙 更新时间:2023-11-03 15:08:06 25 4
gpt4 key购买 nike

我有以下问题:

我有一个带有 execute 和 canexecute 方法的中继命令,但每次我调用 raisecanexecutechanged();它在 relaycommand 中调用 raisecanexecutechanged,为其设置一个新委托(delegate),然后返回到 View 模型。

相同的设置适用于另一个 View 模型。我检查了大约 1000 次有什么不同,但我没有找到任何东西。

如果你能帮助我,我将不胜感激。

    public RelayCommand UpdateAMSCommand { get; private set; }

public AMSSettingsViewModel(IEventAggregator eventAggregator)
{
UpdateAMSCommand = new RelayCommand(OnUpdateAMS, CanUpdateAms);
CustomAMSOffices.ListChanged += listChanged;
CustomAMSContacts.ListChanged += listChanged;
}

private void listChanged(object sender, ListChangedEventArgs e)
{
if (sender != null)
{
if (sender is BindingList<CustomAMSOffice>)
{
BindingList<CustomAMSOffice> temp = (BindingList<CustomAMSOffice>)sender;

if (temp.Count > _amsOfficesItemsCounter)
{
_amsOfficesItemsCounter = temp.Count;

for (int i = 0; i < temp.Count; i++)
{
temp[i].ErrorsChanged += RaiseCanExecuteChanged;
}
}
}
else if (sender is BindingList<CustomAMSContact>)
{
BindingList<CustomAMSContact> temp = (BindingList<CustomAMSContact>)sender;

if (temp.Count > _amsContactsItemsCounter)
{
_amsContactsItemsCounter = temp.Count;

for (int i = 0; i < temp.Count; i++)
{
temp[i].ErrorsChanged += RaiseCanExecuteChanged;
}
}
}
}

UpdateAMSCommand.RaiseCanExecuteChanged();
}

private void RaiseCanExecuteChanged(object sender, DataErrorsChangedEventArgs e)
{
UpdateAMSCommand.RaiseCanExecuteChanged();
}

private bool CanUpdateAms()
{
foreach (var cao in CustomAMSOffices)
{
if (!cao.Check() || cao.HasErrors)
{
return false;
}
}

foreach (var cac in CustomAMSContacts)
{
if (!cac.Check() || cac.HasErrors)
{
return false;
}
}
return true;
}

编辑:我使用的中继命令:https://github.com/briannoyes/WPFMVVM-StarterCode/blob/master/ZzaDashboard/ZzaDashboard/RelayCommand.cs

最佳答案

好的,我只是要复制粘贴一些我正在使用的代码,这样您就可以将它们弹出到您的项目中并使用。

首先,RelayCommand() 类。我从 this msdn page 中提取了这段代码:

public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion

#region Constructors
public RelayCommand(Action<object> execute) : this(execute, null) { }

public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion

#region ICommand Members
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}

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

public void Execute(object parameter)
{
_execute(parameter);
}
#endregion
}

现在我们的 ModelView.cs 类需要继承自 INotifyPropertyChanged 并且将拥有我们的 RaisePropertyChanged()。现在我通常只是把它做成它自己的文件,让我所有的 ModelViews 从它继承,所以代码更干净一些,但你可以随心所欲。

下面是我的设置方式:

基础 View 模型.cs:

public class BaseViewModel : INotifyPropertyChanged
{
internal void RaisePropertyChanged(string prop)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
}
public event PropertyChangedEventHandler PropertyChanged;

// Any other code we want all model views to have
}

现在对于我们的 MainViewModel.cs,我们将从 BaseViewModel 继承,添加我们的事件处理程序,然后运行它!

例子:ServerViewModel.cs

public class ServerViewModel : BaseViewModel
{
public RelayCommand BroadcastMessageCommand { get; set; }

private string _broadcastmessage;
public string broadcastmessage
{
get { return _broadcastmessage; }
set { _broadcastmessage = value; RaisePropertyChanged("broadcastmessage"); }
}

Server server;

public ServerViewModel()
{
server = new Server();
server.run();
BroadcastMessageCommand = new RelayCommand(BroadcastMessage, CanBroadcast);
}

private bool CanBroadcast(object param)
{
if (string.IsNullOrWhiteSpace(broadcastmessage))
return false;
if (!server.running)
return false;
return true;
}

public void BroadcastMessage(object param)
{
server.BroadcastMessage(broadcastmessage);
broadcastmessage = "";
RaisePropertyChanged("broadcastmessage");
}
}

现在 MainView.xaml 中与 Command="{Binding broadcastmessage}" 绑定(bind)的任何内容都将适当更新。在我的例子中,我将它绑定(bind)到一个按钮,如果消息为空,或者如果我们没有连接到服务器,该按钮将被禁用。

希望这些代码示例足以让您朝着正确的方向前进!如果您对此有任何疑问,请告诉我。

关于c# - Relaycommand ICommand.CanExecute 不触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42449723/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com