c# - 禁用与当前 View 对应的当前按钮wpf c#

标签 c# wpf mvvm

我正在尝试为我的导航添加样式,因此当用户在当前选择的 View 上时,相应的按钮将被禁用,因为他们已经在那里时不需要单击它,所以我尝试了不同的 View 测试并没有什么我试图按照我想要的方式工作。
这是按钮代码

 <Button Style="{StaticResource NavButton}"
         Command="{Binding GotoDataMatrixCommand}"
         IsEnabled="{Binding SelectedView}"
         Tag="Document"
         Content="Enter Data">
 </Button>
我在想我可能需要一个转换器吗?
这里的任何方式都是 MVVM 片段
#region Selected View
private object _selectedView;
private object _selectedViewBool;
public object SelectedView
{
   get { return _selectedView; }
   set
   {
      if (_selectedView == _currentView)
      {
         _selectedViewBool = false;
      }
      else
      {
         _selectedViewBool = true;
      }
      OnPropertyChanged(nameof(SelectedView));
   }
}

#endregion

/// here is where I assign _selectedView
private void GoToErrorNotFound()
{
   CurrentTitleBar = "Error Page Not Found";
   CurrentView = _ErrorNotFound;
   _selectedView = _ErrorNotFound;

}
所以我的想法是我会测试将当前 View 放在私有(private)对象中,稍后再测试当前 View 。虽然我的认识是它会一直是真的(或假的)。尽管我不确定是否有人可以帮助我指出正确的方向,但我仍在解决一些问题,我不需要您写下所有内容或任何提示,以更轻松地确定“当前按钮突出显示”
根据命令的请求定义
public ICommand GotoSafetySheetCommand
{
   get
   {
      return _gotoSafetySheetCommand ?? (_gotoSafetySheetCommand = new RelayCommand(
         x =>
         {
            GotoSafetySheet();
         }));
   }
}
这是我的中继命令 CS 文件
public class RelayCommand : ICommand
{
   private readonly Predicate<object> _canExecute;
   private readonly Action<object> _execute;

   public RelayCommand(Action<object> execute)
      : this(execute, null)
   {
      _execute = execute;
   }

   public RelayCommand(Action<object> execute, Predicate<object> canExecute)
   {
      _execute = execute ?? throw new ArgumentNullException(nameof(execute));
      _canExecute = canExecute;
   }

   public bool CanExecute(object parameter)
   {
      return _canExecute == null || _canExecute(parameter);
   }

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

   // Ensures WPF commanding infrastructure asks all RelayCommand objects whether their
   // associated views should be enabled whenever a command is invoked 
   public event EventHandler CanExecuteChanged
   {
      add
      {
         CommandManager.RequerySuggested += value;
         CanExecuteChangedInternal += value;
      }
      remove
      {
         CommandManager.RequerySuggested -= value;
         CanExecuteChangedInternal -= value;
      }
   }

   private event EventHandler CanExecuteChangedInternal;

   public void RaiseCanExecuteChanged()
   {
      CanExecuteChangedInternal.Raise(this);
   }
}

最佳答案

你不应该使用 Command结合 IsEnabled捆绑。一个 ICommand 已经提供了一种方法来确定何时启用控件,即 CanExecute 方法。
CanExecute 初始化你的命令检查需要满足的条件以启用控制并删除 IsEnabled 的委托(delegate)捆绑。控件将确定其IsEnabled基于 CanExecute 的状态绑定(bind)命令的方法,只要它的 CanExecuteChanged 引发事件以及最初绑定(bind)的时间。
我不知道你使用的是哪个命令实现,所以我将提供一个简单的示例 RelayCommand来自 Microsoft command documentation和一个示例 View 模型。

public class MyViewModel
{
   public ICommand GotoDataMatrixCommand { get; }

   public MyViewModel()
   {
      GotoDataMatrixCommand = new RelayCommand(ExecuteGotoDataMatrixCommand, CanExecuteGotoDataMatrixCommand); 
   }

   private void ExecuteGotoDataMatrixCommand()
   {
      // ...your command execution code.
   }

   private bool CanExecuteGotoDataMatrixCommand()
   {
      return _selectedView != _currentView;
   }
}
此外,您必须确保提高CanExecuteChanged每当您的条件更改(或影响条件的任何属性或字段被修改)时的事件,以通知绑定(bind)命令的控件重新查询该命令是否可以执行并设置其IsEnabled基于此的状态。
private void SomeMethod()
{
   // ...this is a sample method that changes _selectedView, _currentView or both
   // so you have to raise the "CanExecuteChanged" event of the command to notify
   // controls to reevalute the `CanExecuteMethod` to get the correct enabled state
   
   GotoDataMatrixCommand.RaiseCanExecuteChange();
}
RaiseCanExecuteChange方法可能特定于此命令实现,您的可能会有所不同。

更新您的编辑。您必须创建一个 CanExecuteSafetySheet如上所示的方法并将其分配给您的RelayCommand .
public ICommand GotoSafetySheetCommand
{
   get
   {
      return _gotoSafetySheetCommand ?? (_gotoSafetySheetCommand = new RelayCommand(
         _ => GotoSafetySheet(),
         _ => CanExecuteSafetySheet()));
   }

   private bool CanExecuteSafetySheet()
   {
      return _selectedView != _currentView;
   }
}
与您的RelayCommand实现你必须调用它每当你改变 _selectedView_currentView触发对 CanExecute 的重新评估关于控制:
CommandManager.InvalidateRequerySuggested()
但是,我建议您更改 RelayCommand反而。删除 CanExecuteChangedInternal事件及其用法。它似乎没有任何用处。然后适应 RaiseCanExecuteChanged方法。
public void RaiseCanExecuteChanged()
{
   CanExecuteChanged.Raise(this);
}
现在不再使用 CommandManager.InvalidateRequerySuggested ,你打电话:
GotoSafetySheetCommand.RaiseCanExecuteChanged();

关于c# - 禁用与当前 View 对应的当前按钮wpf c#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64107972/

相关文章:

c# - 使用正确的包 ://URI Format

wpf - ListView 基于绑定(bind)值的不同控件

主要方法的 C# 单元测试 - 操作命令行参数 - Microsoft Visual Studio 测试工具

c# - 调试 AxShockwaveFlash

wpf - 在选项卡项中查找用户控件的子项

wpf - 我应该在哪里定义我的数据模板?

c# - MVVM中事件的处理方式

c# - Asp.Net Core 2.0.1 的 Serilog 设置不生成日志

c# - 使用 C# MVC4 并将 DbContext 类名称与 ConnectionString 名称匹配以使用正确的数据库?

wpf - mvvm中的businesslogic