尝试使用下面的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应用)

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,我也不知道/不理解它。如果有人可以提供一些与此有关的信息,那真是太好了。

但是您应该注意其用法:如果您离开Page,则应该销毁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/

10-10 01:34