![](/img/trans.png)
[英]The name 'ViewBag' does not exist in the current context - Visual Studio 2015
[英]The name “CommandManager” does not exist in the current context (Visual Studio 2015)
尝试使用下面的RelayCommand类我收到错误消息:“名称”CommandManager“在当前上下文中不存在”。 根据这篇文章, 类库无法识别CommandManager类,我试图通过在“添加引用”上添加一个名为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应用程序)
RelayCommand.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));
}
}
}
}
您正在混合标准的.NET Framework
WPF( CommandManager
)和用于UWP开发的较小的.NET Core Framework
。
不幸的是,它们在所有领域都不是100%兼容。 您不能使用RelayCommand
类,因为它是在那里编写的 - 您需要重写依赖于CommandManager
的部分。
当你创建一个基类(继承)类的类时,尝试之后打开实例:
public class RelayCommand : ICommand
{
public RelayCommand()
{}
private readonly Action<object> _Execute;
private readonly Func<object, bool> _CanExecute;
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
这不适用于netstandard
我复制了你的代码,我得到了
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
“this”不带2个参数
我也明白了
public class RelayCommand : ICommand
{
public RelayCommand()
{ }
不实现ICommand - > CanExecuteChanged
所以这不会奏效
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.