gpt4 book ai didi

c# - 当前上下文中不存在名称 "CommandManager"(Visual Studio 2015)

转载 作者:太空狗 更新时间:2023-10-29 18:28:49 25 4
gpt4 key购买 nike

尝试使用下面的 RelayCommand 类时,我收到了错误消息:“名称“CommandManager”在当前上下文中不存在”。根据这篇文章Class library does not recognize CommandManager class我试图通过在“添加引用”上添加一个名为 PresentationCore 的程序集来解决问题。不幸的是“在机器上找不到框架程序集”。我卸载了 Microsoft.NETCore.UniversalWindowsPlatform 并按照某些帖子中的建议重新安装它,然后修复了 Visual Studio,但这并没有改变任何东西。这是我的失败还是错误?作为新手,我总是倾向于认为我忽略了一些东西;-)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace MyApplication.Viewmodels
{
public class RelayCommand : ICommand
{
private readonly Action<object> _Execute;
private readonly Func<object, bool> _CanExecute;

public RelayCommand(Action<object> execute)
: this(execute, null)
{

}

public RelayCommand(Action<object> execute, Func<object, bool> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute", "Execute cannot be null.");
}

_Execute = execute;
_CanExecute = canExecute;
}

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

public void Execute(object parameter)
{
_Execute(parameter);
}

public bool CanExecute(object parameter)
{
if (_CanExecute == null)
{
return true;
}

return _CanExecute(parameter);
}
}
}

最佳答案

.NETCore 中不存在 CommandManager。我写了我自己的解释,因为我和你现在的情况完全一样。 (使用 MVVM 设计模式开发 UWP 应用程序)

中继命令.cs:

using System;
using System.Windows.Input;

namespace MVVMBoostUniversalWindowsApp
{
public class RelayCommand : ICommand
{
private readonly Action execute;
private readonly Func<bool> canExecute;

public RelayCommand(Action execute)
: this(execute, null)
{ }

public RelayCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute is null.");

this.execute = execute;
this.canExecute = canExecute;
this.RaiseCanExecuteChangedAction = RaiseCanExecuteChanged;
SimpleCommandManager.AddRaiseCanExecuteChangedAction(ref RaiseCanExecuteChangedAction);
}

~RelayCommand()
{
RemoveCommand();
}

public void RemoveCommand()
{
SimpleCommandManager.RemoveRaiseCanExecuteChangedAction(RaiseCanExecuteChangedAction);
}

bool ICommand.CanExecute(object parameter)
{
return CanExecute;
}

public void Execute(object parameter)
{
execute();
SimpleCommandManager.RefreshCommandStates();
}

public bool CanExecute
{
get { return canExecute == null || canExecute(); }
}

public void RaiseCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, new EventArgs());
}
}

private readonly Action RaiseCanExecuteChangedAction;

public event EventHandler CanExecuteChanged;
}
}

这是我的 SimpleCommandManager.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace MVVMBoostUniversalWindowsApp
{
public static class SimpleCommandManager
{
private static List<Action> _raiseCanExecuteChangedActions = new List<Action>();

public static void AddRaiseCanExecuteChangedAction(ref Action raiseCanExecuteChangedAction)
{
_raiseCanExecuteChangedActions.Add(raiseCanExecuteChangedAction);
}

public static void RemoveRaiseCanExecuteChangedAction(Action raiseCanExecuteChangedAction)
{
_raiseCanExecuteChangedActions.Remove(raiseCanExecuteChangedAction);
}

public static void AssignOnPropertyChanged(ref PropertyChangedEventHandler propertyEventHandler)
{
propertyEventHandler += OnPropertyChanged;
}

private static void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
// this if clause is to prevent an infinity loop
if (e.PropertyName != "CanExecute")
{
RefreshCommandStates();
}
}

public static void RefreshCommandStates()
{
for (var i = 0; i < _raiseCanExecuteChangedActions.Count; i++)
{
var raiseCanExecuteChangedAction = _raiseCanExecuteChangedActions[i];
if (raiseCanExecuteChangedAction != null)
{
raiseCanExecuteChangedAction.Invoke();
}
}
}
}
}

不要问我为什么 .NETCore 中没有 CommandManager 我也不知道/不了解它。如果有人可以提供一些与此相关的信息,那将是很好的消息。

但是您应该关心用法:如果您离开一个页面,您应该销毁 SimpleCommandManager 中不再使用但被引用的剩余命令。如果有人需要,我也有解决方案,我可以编辑我的帖子。

这实际上只是一个非常简单/原始的解决方案,没有什么特别的。但它有效。

编辑:

为了提供更好的使用示例和基础,这也是我的基础 ViewModel。如上所述,离开当前页面时应该调用“RemoveCommands”。否则这些将永远不会被 GC 释放。

ViewModel.cs

using System.ComponentModel;
using System;
using System.Runtime.CompilerServices;
using Windows.UI.Xaml.Controls;
using System.Collections.Generic;
using Windows.UI.Core;

namespace MVVMBoostUniversalWindowsApp
{
public abstract class ViewModel : INotifyPropertyChanged
{
protected ViewModel()
{
DispatcherObject = CoreWindow.GetForCurrentThread().Dispatcher;
SimpleCommandManager.AssignOnPropertyChanged(ref this.PropertyChanged);
_commandsList = new List<RelayCommand>();
}

private List<RelayCommand> _commandsList;

protected RelayCommand CreateCommand(Action execute)
{
return CreateCommand(execute, null);
}

protected RelayCommand CreateCommand(Action execute, Func<bool> canExecute)
{
var tempCmd = new RelayCommand(execute, canExecute);
if (_commandsList.Contains(tempCmd))
{
return _commandsList[_commandsList.IndexOf(tempCmd)];
}
else
{
_commandsList.Add(tempCmd);
return tempCmd;
}
}

public void RemoveCommands()
{
for (var i = 0; i < _commandsList.Count; i++)
{
_commandsList[i].RemoveCommand();
}
}

public virtual CoreDispatcher DispatcherObject { get; protected set; }

public event PropertyChangedEventHandler PropertyChanged;

protected void ChangeProperty<T>(ref T property, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(property, value))
{
return;
}
else
{
property = value;

OnPropertyChanged(propertyName);
}
}

protected void OnPropertyChangedEmpty()
{
OnPropertyChanged(String.Empty);
}

protected void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

关于c# - 当前上下文中不存在名称 "CommandManager"(Visual Studio 2015),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34996198/

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