[英]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.