c# - 为 BindingGroup 设置 IsDirty
问题描述
我BindingGroup
用于跟踪 ViewModel 中数据的更改,以便保存或回滚。我的视图看起来像这样:
<UserControl x:Class="UserManagement.Client.Views.UserDetail"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:prism="http://prismlibrary.com/"
xmlns:viewModels="clr-namespace:UserManagement.Client.ViewModels"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance viewModels:IUserDetailViewModel}"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
<StackPanel.BindingGroup>
<BindingGroup x:Name="BindingGroup">
<BindingGroup.ValidationRules>
<client:UserDetailValidation ValidationStep="ConvertedProposedValue"/>
</BindingGroup.ValidationRules>
</BindingGroup>
</StackPanel.BindingGroup>
<TextBlock Text="Display Name:"/>
<TextBox Text="{Binding User.DisplayName}"/>
<ListView ItemsSource="{Binding UserGroups}">
<ListView.View>
<GridView>
<GridViewColumn Header="Display Name" DisplayMemberBinding="{Binding DisplayName}"/>
</GridView>
</ListView.View>
</ListView>
<Button Content="Edit Groups" Command="{Binding EditGroupsCommand}"/>
<Button Content="Save" Command="{Binding SaveCommand}" CommandParameter="{Binding ElementName=BindingGroup}"/>
<Button Content="Cancel" Command="{Binding CancelCommand}" CommandParameter="{Binding ElementName=BindingGroup}"/>
</StackPanel>
</UserControl>
我的 ViewModel 看起来像这样:
public class UserDetailViewModel : BindableBase, IUserDetailViewModel
{
private const string DialogParameterNameAssignedGroups = "AssignedGroups";
private const string DialogTitle = "GroupSelection";
private readonly IDialogService _dialogService;
private readonly IUserClientService _userClientService;
private User _user;
public UserDetailViewModel(IDialogService dialogService, IUserClientService userClientService)
{
_dialogService = dialogService;
_userClientService = userClientService;
SaveCommand = new DelegateCommand<BindingGroup>(Save, CanSave);
CancelCommand = new DelegateCommand<BindingGroup>(Cancel, CanCancel);
EditGroupsCommand = new DelegateCommand(EditGroups, CanEditGroups);
}
public User User
{
get => _user;
set
{
SetProperty(ref _user, value);
RaisePropertyChanged(nameof(User));
RaisePropertyChanged(nameof(UserGroups));
}
}
public ICollection<Group> UserGroups => new ObservableCollection<Group>(User.Groups);
public DelegateCommand<BindingGroup> SaveCommand { get; }
public DelegateCommand EditGroupsCommand { get; }
public DelegateCommand<BindingGroup> CancelCommand { get; }
private static bool CanSave(BindingGroup bindingGroup)
{
return bindingGroup.IsDirty;
}
private void Save(BindingGroup bindingGroup)
{
if (!bindingGroup.CommitEdit()) return;
bindingGroup.BeginEdit();
_userClientService.UpdateUser(User);
}
private static bool CanCancel(BindingGroup bindingGroup)
{
return bindingGroup.IsDirty;
}
private static void Cancel(BindingGroup bindingGroup)
{
bindingGroup.CancelEdit();
bindingGroup.BeginEdit();
}
private bool CanEditGroups()
{
return _user != null;
}
private void EditGroups()
{
_dialogService.ShowDialog(DialogTitle, new DialogParameters
{
{DialogParameterNameAssignedGroups, new ObservableCollection<Group>(_user.Groups)}
}, HandleDialogResult);
}
private void HandleDialogResult(IDialogResult dialogResult)
{
if (dialogResult.Result != ButtonResult.OK) return;
var assignedGroups = dialogResult.Parameters.GetValue<ICollection<Group>>(
DialogParameterNameAssignedGroups);
_user.Groups.Clear();
foreach (var assignedGroup in assignedGroups)
{
_user.Groups.Add(assignedGroup);
}
RaisePropertyChanged(nameof(UserGroups));
}
}
验证类什么都不做:
public class UserDetailValidation : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
return ValidationResult.ValidResult;
}
}
如果我更改UserName
. 我可以保存更改或取消(任何一个选项都会禁用按钮)。但是,如果我更改UserGroups
集合(使用单独的对话框),按钮将不会启用,但 UI 会更新。当我更改属性时,我必须更改哪些BindingGroup
集合?IsDirty
UserGroups
解决方案
我可能会错过一些东西,但你为什么不在 HandleDialogResult 中设置 IsDirty=true 呢?否则 ObservableCollection 会提供一个事件 CollectionChanged ,您可以注册该事件并在该集合发生更改时收到通知,因此您可以在那里更改 isDirty 。
推荐阅读
- sql - 在 oracle 表中查找缺失的 ID
- json - 导入xlsx并解析成json
- z3 - 与 z3 版本 4.8.4 相比,Z3_get_numeral_double API 在 z3 版本 4.8.10 中给出不同的结果
- selenium - 在我的自动化项目的测试类中调用驱动程序时,我遇到了空指针问题。我该如何解决这个问题?
- php - 解析具有相同名称的多个标头
- bash - 使用 echo 逐行打印一个数字序列
- django - 如何在 django 中预定义关联的模型外键
- sql - 检查特定条件下的重复值
- javascript - 如何在 NodeJS 后端应用程序上允许 CORS
- facebook - 页面评级需要两因素身份验证