【发布时间】:2020-08-14 01:10:48
【问题描述】:
我正在使用 MVVM 在 WPF 中创建应用程序,在其中显示一个带有保存文件名和路径文本框的页面。这些文本框经过大量实时验证(路径太短、太长、无效字符等),并且“保存”按钮只有在文件和路径都有效时才会变为活动状态。但是,我会留下一些最终检查,例如目录是否存在、文件是否已存在等,直到用户点击保存按钮。
问题是我有点作弊并使用按钮click 和Navigation Service 和command 在ViewModel 中进行最后一分钟的保存或清理。在这种情况下,该命令将处理,但当它完成时,无论验证结果如何,单击都会立即触发。所以,不知何故,我需要启用或禁用 click 事件,直到我们知道最终的验证结果。
查看:
<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。不幸的是,我看过的所有教程都只涉及通过文本框等 UI 元素进行绑定,而不是绑定到变量背后的代码。这是我尝试的绑定方法:
public Pg9BackupIntro()
{
InitializeComponent();
Binding binding = new Binding();
binding.Source = ViewModel or Datacontext; //<- don't understand syntax here
binding.Path = ViewModel.SaveClickEnabled;
}
另一个想法是可能使用 2 个按钮; command 为 1,click 为 1。 click 按钮将永远不可见,但会根据 VM 中设置的属性以某种方式触发单击。
这两种可能吗?我试过两者都做,但我的菜鸟妨碍了。我也尝试绑定到IsHitTestVisible,但这也会禁用command。
<Button IsHitTestVisible="{Binding SaveClickEnabled}" //<- Disables command too
Click="Pg9SaveBtnClick"
Command="{Binding SaveBtnCommand}">
Save
</Button>
有没有简单的方法来做到这一点?
【问题讨论】:
-
“问题是我有点作弊,并使用导航服务的按钮单击” 不要作弊 ;-)
-
如果您向我们展示代码 sn-p 以及您尝试执行的操作,我们会更清楚
-
@Rans:我更新了问题以显示代码。后面代码中的绑定是我知道会起作用的东西,但我就是想不出在没有 UI 元素的情况下绑定的措辞。我不需要 SaveClickEnabled 绑定说 Textbox.Text,只是一个变量或绑定本身应该可以工作。对吗?
标签: c# wpf mvvm data-binding