[英]Binding checkbox issue in WPF MVVM
我在从VM获取复选框IsChecked绑定值的值时遇到问题。 (我正在使用MVVM Light)。
我的问题 :更改复选框IsChecked时,它不会重新触发绑定到的VM属性。
下面是代码。
我有一个带有布尔值的类(在类文件中)。
public class Rights
{
public bool bSales { get; set; }
public bool bProduct { get; set; }
public bool bZone { get; set; }
public bool bPercentage { get; set; }
public bool bUser { get; set; }
}
这是我的复选框将绑定到的属性(在VM中)。
private Rights user_Rights;
public Rights User_Rights
{
get { return user_Rights; }
set { Set(ref user_Rights, value); }
}
以下是我的“全选”复选框(在VM中)的属性。
private bool? rights_All;
public bool? Rights_All
{
get { return rights_All; }
set
{
Set(ref rights_All, value);
if (value == true)
{
User_Rights = new Rights() { bSales = true, bProduct = true, bPercentage = true, bZone = true, bUser = true };
}
else if(value == false)
{
User_Rights = new Rights() { bSales = false, bProduct = false, bPercentage = false, bZone = false, bUser = false };
}
}
}
最后,下面是绑定的XAML。
<CheckBox Content="Sales PIC" IsChecked="{Binding User_Rights.bSales,Mode=TwoWay}" />
<CheckBox Content="Product" IsChecked="{Binding User_Rights.bProduct,Mode=TwoWay}" />
<CheckBox Content="Zone" IsChecked="{Binding User_Rights.bZone,Mode=TwoWay}" />
<CheckBox Content="Percentage" IsChecked="{Binding User_Rights.bPercentage}" />
<CheckBox Content="User" IsChecked="{Binding User_Rights.bUser}" />
<CheckBox Content="Select All" IsChecked="{Binding Rights_All}" />
关于我在哪里做错的任何建议? 谢谢。
我不知道您的viewmodel基类是什么,所以我只用了自己的。 我不知道您的Set()
方法如何工作; 您可能需要一点适应性。 那一定是你的工作; 轮到你了。 我写这篇文章是因为向您解释逻辑要比编写代码花费更多的时间。 您应该阅读并理解该代码,而不是简单地将其粘贴到您的项目中。
请注意,我已经使用常规的C#命名约定编写了此代码。 布尔属性不再具有b
前缀。 这意味着您必须从XAML绑定中的路径中删除该前缀。
还要注意,我将Rights_All
重Rights_All
为All
, 并将其移至其他视图模型 。 现在它是Rights
视图模型的成员。 这也将需要更改绑定。
您应该考虑将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;
}
}
}
}
}
这是我的解决方案的答案(在收到@Ed Plunkett和@zaitsman的建议后),我对Model中的一个类实现了INotifyProperty(通过使用MVVM Light方法)。
对于我的模型课。
public class Rights: ViewModelBase
{
public Rights()
{
_bSalesPIC = false;
_bZone = false;
... (etc)
_bAll = false;
}
private bool _bSalesPIC;
public bool bSalesPIC
{
get { return _bSalesPIC; }
set
{
Set(ref _bSalesPIC, value);
TriggerAll();
}
}
private bool _bZone;
public bool bZone
{
get { return _bZone; }
set
{
Set(ref _bZone, value);
TriggerAll();
}
}
private bool? _bAll;
public bool? bAll
{
get { return _bAll; }
set
{
Set(ref _bAll , value);
if (value == true)
{
_bSalesPIC = true;
_bZone = true;
RaisePropertyChanged("bSalesPIC");
RaisePropertyChanged("bZone");
}
else if (value == false)
{
_bSalesPIC = false;
_bZone = false;
RaisePropertyChanged("bSalesPIC");
RaisePropertyChanged("bZone");
}
}
}
private void TriggerAll()
{
if (_bSalesPIC && _bZone && etc)
bAll = true;
else if (!_bSalesPIC && !_bZone && etc)
bAll = false;
else
bAll = null;
}
对于我的VM。
private Rights user_Rights;
public Rights User_Rights
{
get { return user_Rights; }
set { Set(ref user_Rights, value); }
}
对于我的视图(XAML)。
<CheckBox Content="Sales PIC" IsChecked="{Binding User_Rights.bSalesPIC}" />
<CheckBox Content="Sales Input" IsChecked="{Binding User_Rights.bSalesInput}" />
<CheckBox Content="Product" IsChecked="{Binding User_Rights.bProduct}" />
<CheckBox Content="Zone" IsChecked="{Binding User_Rights.bZone}" />
<CheckBox Content="Percentage" IsChecked="{Binding User_Rights.bPercentage}" />
<CheckBox Content="User" IsChecked="{Binding User_Rights.bUser}" />
<CheckBox Content="Select All" IsChecked="{Binding User_Rights.bAll}" />
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.