我有一个wpf mvvm应用程序。我尝试写复选框列表控件。
我可以绑定复选框列表元素。
添加到此问题,我想获得所选复选框列表元素值的总和
我添加了DependencyProperty并将其绑定到视图模型属性
但是,他们互不开火。
CheckBoxList用户控件Xaml
<ListBox x:Name="ItemsControl" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Text}" IsChecked="{Binding IsSelected, Mode=TwoWay}"
Checked="CheckBox_Checked" Unchecked="CheckBox_Checked" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
CheckBoxList代码隐藏
public partial class CheckBoxList : UserControl
{
public CheckBoxList()
{
InitializeComponent();
}
public static readonly DependencyProperty SelectedCheckBoxItemsValueProperty =
DependencyProperty.Register("SelectedCheckBoxItemsValue", typeof(int), typeof(CheckBoxList),
new FrameworkPropertyMetadata(
0,
new FrameworkPropertyMetadata(0, OnSelectedItemsChanged));
public int SelectedCheckBoxItemsValue
{
get { return (int)GetValue(SelectedCheckBoxItemsValueProperty); }
set { SetValue(SelectedCheckBoxItemsValueProperty, value); }
}
private static int GetSelectedCheckBoxItemsValue(DependencyObject obj)
{
return (int)obj.GetValue(SelectedCheckBoxItemsValueProperty);
}
private static void OnSelectedItemsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
CheckBoxList checkboxList = obj as CheckBoxList;
ObservableCollection<ISelectableItem> items = checkboxList.DataContext as ObservableCollection<ISelectableItem>;
foreach (var item in items)
{
item.IsSelected = (GetSelectedCheckBoxItemsValue(obj) & item.Value) != 0;
}
}
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
CheckBoxList checkboxList = sender as CheckBoxList;
ObservableCollection<ISelectableItem> coll = ItemsControl.DataContext as ObservableCollection<ISelectableItem>;
if (coll == null) return;
int count = 0;
foreach (var item in coll)
{
if (item.IsSelected)
{
count += item.Value;
}
}
SelectedCheckBoxItemsValue = count;
}
}
SelectableItem类
public interface ISelectableItem : INotifyPropertyChanged
{
bool IsSelected { get; set; }
string Text { get; set; }
int Value { get; set; }
string GroupName { get; set; }
}
public class SelectableItem : ISelectableItem
{ ....
ViewModel属性
public int SelectedCheckBoxEnumItemsValue
{
get
{
return _selectedCheckBoxEnumItemsValue;
}
set
{
_selectedCheckBoxEnumItemsValue = value;
NotifyOfPropertyChange("SelectedCheckBoxEnumItemsValue");
}
}
在Binder课程
string selectedItemPropertyName = "Selected" + viewModelProperty.Name + "Value";
var property = viewModelProperties.FirstOrDefault(p => p.Name.Contains(selectedItemPropertyName));
if (property != null)
{
var selectedItemOrValueBinding = new Binding(property.Name)
{
Mode = property.CanWrite ? BindingMode.TwoWay : BindingMode.OneWay,
ValidatesOnDataErrors = Attribute.GetCustomAttributes(property, typeof(ValidationAttribute), true).Any()
};
BindingOperations.SetBinding(control, CheckBoxList.SelectedCheckBoxItemsValueProperty, selectedItemOrValueBinding);
}
答案 0 :(得分:0)
以下代码解决了您的问题..
请注意视图模型的隔离。
<StackPanel>
<TextBlock Text="{Binding Count}"></TextBlock>
<ListBox x:Name="ItemsControl" ItemsSource="{Binding CheckList}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Name="item" Content="{Binding Text}" IsChecked="{Binding IsSelected, Mode=TwoWay}" Command="{Binding CheckboxCheckedCommand}" CommandParameter="{Binding IsChecked, ElementName=item}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MasterViewModel();
}
}
public class MasterViewModel : INotifyPropertyChanged
{
private List<CheckBoxItem> checkList;
private int count;
public int Count
{
get
{
return count;
}
set
{
count = value;
OnPropertyChanged("Count");
}
}
public List<CheckBoxItem> CheckList
{
get
{
return checkList;
}
set
{
checkList = value;
OnPropertyChanged("CheckList");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public MasterViewModel()
{
checkList = new List<CheckBoxItem>();
for (int i = 0; i < 5; i++)
{
CheckBoxItem item = new CheckBoxItem();
item.Text = i.ToString();
item.IsSelected = false;
item.CheckboxCheckedCommand = new RelayCommand(new Action<object>(ExecuteCheckCommand));
checkList.Add(item);
}
}
private void ExecuteCheckCommand(object parameter)
{
if (parameter.GetType() == typeof(bool))
{
bool value = bool.Parse(parameter.ToString());
int val = count;
if (value)
{
val++;
}
else
{
val--;
}
Count = val;
}
}
private void OnPropertyChanged(string p)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
}
}
public class CheckBoxItem : INotifyPropertyChanged
{
private bool isSelected;
private string text;
public string Text
{
get
{
return text;
}
set
{
text = value;
OnPropertyChanged("Text");
}
}
public bool IsSelected
{
get
{
return isSelected;
}
set
{
isSelected = value;
OnPropertyChanged("IsSelected");
}
}
public ICommand CheckboxCheckedCommand
{
get;
set;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string p)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
}
}
public class RelayCommand : ICommand
{
private Action<object> executeCommand;
public RelayCommand(Action<object> executeCommand)
{
this.executeCommand = executeCommand;
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
executeCommand(parameter);
}
}