c# - 在不禁用命令的情况下禁用按钮单击事件?
问题描述
我正在使用 MVVM 在 WPF 中创建应用程序,其中我显示一个带有保存文件名和路径文本框的页面。这些文本框经过大量实时验证(路径太短、太长、无效字符等),并且“保存”按钮只有在文件和路径都有效时才会变为活动状态。但是,我将留下一些最终检查,例如目录是否存在、文件是否已存在等,直到用户点击保存按钮。
问题是我有点作弊并使用按钮和按钮在click
ViewModel中进行最后一分钟的保存或清理。在这种情况下,该命令将处理,但当它完成时,无论验证结果如何,单击都会立即触发。所以,不知何故,我需要启用或禁用 click 事件,直到我们知道最终的验证结果。Navigation Service
command
看法:
<TextBlock>
Backup Name:
</TextBlock>
<TextBlock Text="{Binding Path=(Validation.Errors)/ErrorContent,
ElementName=BackupFileNameTextBox}"/>
<TextBox x:Name="BackupFileNameTextBox"
Text="{Binding BackupFileName, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnNotifyDataErrors=True}"/>
... File Path Code same as above...
<Button Click="Pg9SaveBtnClick"
Command="{Binding SaveBtnCommand}">
Save
</Button>
代码背后
public Pg9BackupIntro()
{
InitializeComponent();
}
private void Pg9SaveBtnClick(object sender, RoutedEventArgs e)
{
// What I want to do
if(binding.ViewModel.SaveClickEnabled) //<- Something like this
{
if (NavigationService.CanGoForward)
NavigationService.GoForward();
else
{
Pg10Backup page = new Pg10Backup();
NavigationService.Navigate(page);
}
}
}
private void Pg9BackBtnClick(object sender, RoutedEventArgs e)
{
NavigationService.GoBack();
}
视图模型:
public RelayCommand SaveBtnCommand { get; private set; }
public Pg9BackupIntroViewModel()
{
SetupBackupSave();
SaveBtnCommand = new RelayCommand(SetBackupFileData, CanSetBackupFileData);
}
private string _backupFileName;
public string BackupFileName
{
get { return _backupFileName; }
set
{
_backupFileName = value;
validateFileName();
RaisePropertyChanged();
}
}
... BackupFilePath prop same as above...
private bool _saveClickEnabled = false;
public bool SaveClickEnabled
{
get { return _saveClickEnabled; }
set
{
_saveClickEnabled = value;
RaisePropertyChanged();
}
}
private bool CanSetBackupFileData(object obj)
{
if(HasErrors)
return false;
return true;
}
private void SetBackupFileData(object obj)
{
finalValidation();
if(!HasErrors)
SaveClickEnabled = true;
else
SaveClickEnabled = false;
}
我能想到的最简单的事情(如上所示)是在 VM 中创建一个名为“SaveClickEnable”的属性,并在绑定到该属性的代码中。然后我们可以简单地检查 click 事件处理程序中的属性并调用Navigation Service
if 一切正常。不幸的是,我看过的所有教程都只涉及通过文本框等 UI 元素进行绑定,而不是绑定到变量背后的代码。这是我尝试的绑定方法:
public Pg9BackupIntro()
{
InitializeComponent();
Binding binding = new Binding();
binding.Source = ViewModel or Datacontext; //<- don't understand syntax here
binding.Path = ViewModel.SaveClickEnabled;
}
另一个想法是可能使用 2 个按钮;1 代表command
, 1 代表click
。该click
按钮将永远不可见,但会根据 VM 中设置的属性以某种方式触发单击。
这些都可能吗?我试过两者都做,但我的菜鸟妨碍了。我也尝试过绑定,IsHitTestVisible
但这也会禁用command
.
<Button IsHitTestVisible="{Binding SaveClickEnabled}" //<- Disables command too
Click="Pg9SaveBtnClick"
Command="{Binding SaveBtnCommand}">
Save
</Button>
有没有一种简单的方法可以做到这一点?
解决方案
我通过创建一个隐藏的复选框并将其IsChecked
属性绑定到SaveClickEnabled
. 然后我只需检查 click 方法中复选框的值,如果出现错误,它会绕过导航代码。
看法:
<CheckBox x:Name="ClickEnabledCheckbox"
Visibility="Collapsed"
IsChecked="{Binding SaveClickEnabled}"/>
代码隐藏:
private void Pg9BackupBtnClick(object sender, RoutedEventArgs e)
{
if(ClickEnabledCheckbox.IsChecked == true)
{
...Navigate to next View
}
}
视图模型:
private bool _saveClickEnabled = false;
public bool saveClickEnabled
{
get { return _backupClickEnabled; }
set
{
if (HasErrors)
_backupClickEnabled = false;
_backupClickEnabled = true;
RaisePropertyChanged();
}
}
它的美妙之处在于,我不想在用户可能正在输入有效文件路径或我们可以为他们创建的路径的整个过程中对他们咆哮。所以这只检查点击/命令上的那些类型的错误,当用户试图纠正他/她的错误时,错误就会消失,直到下一次按下。
我唯一的愿望是它更干净一些,似乎应该有办法消除复选框。
推荐阅读
- wpf - 取消 WPF 中长时间运行的渲染操作
- python - 为什么他们在编写 csv 时使用集合?)困惑我
- reactjs - 在 next.js 中使用 firebase 时出现错误
- android - 使用动画从上到左动画复合 Drawable
- stripe-payments - 使用附加卡对客户进行条带化,但没有默认付款方式
- android - 更改 ListView 项中的布局元素
- sql - 需要从源表中获取布尔类型列作为 varchar 并在 Amazon redshift 的目标表中存储为 varchar
- python - 来自前 2 个 Dataframe 列的 2 元素列表列表
- python - 使用 Pandas read_html 抓取表格并识别标题
- angular - 唯一 userId 的异步验证器不起作用