我不知道你的 Set() 方法如何运作;这可能需要你的一点调整 . 那轮到你了 . 我这样写是因为向你解释逻辑比编写代码需要更长的时间 . 您应该阅读此代码并理解它,而不是简单地将其粘贴到您的项目中 .
请注意,我使用传统的C#命名约定编写了这个 . 布尔属性不再具有 b 前缀 . 这意味着您必须从XAML中绑定的路径中删除该前缀 .
另请注意,我将 Rights_All 重命名为 All ,并将其移至另一个viewmodel . 它现在是 Rights viewmodel的成员 . 这也需要更改绑定 .
您应该考虑使用 Flags 枚举作为您的权利 . 这将简化代码,并使将来更容易添加其他权限 .
public class Rights : ViewModelBase
{
private bool _sales;
public bool Sales {
get { return _sales; }
set { SetRightFlag(ref _sales, value); }
}
private bool _product;
public bool Product
{
get { return _product; }
set { SetRightFlag(ref _product, value); }
}
private bool _zone;
public bool Zone
{
get { return _zone; }
set { SetRightFlag(ref _zone, value); }
}
private bool _percentage;
public bool Percentage
{
get { return _percentage; }
set { SetRightFlag(ref _percentage, value); }
}
private bool _user;
public bool User
{
get { return _user; }
set { SetRightFlag(ref _user, value); }
}
// This logic needs to happen in five different setters, so I put it in a
// method.
private bool SetRightFlag(ref bool field, bool value, [System.Runtime.CompilerServices.CallerMemberName] string propName = null)
{
if (field != value)
{
Set(ref field, value, propName);
UpdateAll();
return true;
}
return false;
}
// I made this its own method as well, for cleanliness and clarity, even though
// it's only called once.
protected void UpdateAll()
{
// Don't call the All setter from here, because it has side effects.
if (User && Percentage && Zone && Product && Sales)
{
_all = true;
OnPropertyChanged(nameof(All));
}
else if (!User && !Percentage && !Zone && !Product && !Sales)
{
_all = false;
OnPropertyChanged(nameof(All));
}
else if (All.HasValue)
{
_all = null;
OnPropertyChanged(nameof(All));
}
}
private bool? _all = null;
public bool? All
{
get { return _all; }
set {
if (_all != value)
{
Set(ref _all, value);
if (_all.HasValue)
{
User = Percentage = Zone = Product = Sales = (bool)_all;
}
}
}
}
}