I've solved my issue using a Command along with a Tag containing the name of the model property I want set and a CommandParameter set to a multi-binding that is bound to the Tag and the Checkbox's IsSelected property. The code follows.
Up vote 0 down vote favorite share g+ share fb share tw.
I have a ListView containing several GridViewColumns. Several of the columns are checkboxes. Each column header consists of a checkbox as well, with the intention of checking/unchecking all the checkboxes in that column.
Each row's checkboxes are bound to properties in my view model. I've seen several postings where the scenario is a single column of checkboxes, but none of those solutions will work for me, as I have 4 columns of checkboxes. I also need to persist the state of the selections from one visit to the next (all, some or none of the checkboxes in a column could be checked).
Here's an abbreviated version of the XAML for my ListView: I've tried using Commands and Command Parameters, PropertyChanged events on the Checked property, and handling the Checked event in my code behind, but nothing gives me enough information to know what to change in the collection I'm bound to. I suppose I could create a separate event handler for each, but I'd like to be able to handle this in a single event handler if possible, because eventually I will be creating a custom control that is a bit more malluable in terms of the columns displayed. Thanks in advance c# wpf listview checkbox link|improve this question edited May 12 '11 at 16:56 asked May 11 '11 at 19:08KyleLib9419 60% accept rate.
– Haris Hasan May 11 '11 at 19:24 I'm trying to figure out how to link up to my view model and determine which boolean property I need to effect on each item in my AveragingParameters collection. H.B.'s post below might be the ticket. – KyleLib May 11 '11 at 19:42 I'm not sure I'm understanding the problem.
If you bind each column to an individual property/field in your ModelView then when that checkbox state changes so will your underlying bound object. There is not need to determine which boolean property, it's explicit via the binding. Maybe I don't understand the question.
– SRM May 11 '11 at 20:17 @SRM, Maybe I'm missing something, but the state of my Model is being persisted, and I need to retain the boolean value of each item in the grid on subsequent visits (Apologies for not mentioning that in my orignal post. ) Seems your solution would break this. That's why I couldn't use triggers.
FYI, I did solve my issue using multibinding, solution to be posted shortly. – KyleLib May 11 '11 at 16:28.
I've solved my issue using a Command along with a Tag containing the name of the model property I want set and a CommandParameter set to a multi-binding that is bound to the Tag and the Checkbox's IsSelected property. The code follows: My View's Xaml Resources: My View's Xaml: My MultiValueConverter: public class NameValueMultiBindingConverter : IMultiValueConverter { public object Convert(object values, Type targetType, object parameter, System.Globalization. CultureInfo culture) { var parameters = (object)values; return new NameValueConverterResult { Name = (string)parameters0, Value = parameters1 }; } public object ConvertBack(object value, Type targetTypes, object parameter, System.Globalization.
CultureInfo culture) { throw new NotImplementedException(); } } The result object I'm using in the converter: public class NameValueConverterResult { //The name of the model property to set public string Name { get; set; } //The value we're setting it to public object Value { get; set; } } The DelegateCommand (I'm using PRISM) and handler in my View Model public ICommand SelectAllCheckedCommand { get; private set; } private void OnSelectAllCheckedCommand(object arg ) { if (arg == null ||!(arg is NameValueConverterResult)) return; NameValueConverterResult prop = arg as NameValueConverterResult; //Reflect on the model to find the property we want to update. PropertyInfo propInfo = Averagers.FirstOrDefault().GetType(). GetProperty(prop.
Name); if (propInfo == null) return; //Set the property on the Model foreach (var item in Averagers) propInfo. SetValue(item, prop. Value, null); } I hope I'm not abusing StackOverflow providing the solution I came up with.
I wasn't sure of the etiquette here.
Just hand over as much info as needed and do the rest via reflection, e.g. // This method could be used for all columns, // as long as they contain the necessary info // which should be provided in the XAML: // - Item Collection // - Property Name private void CheckBox_Click(object sender, RoutedEventArgs e) { var cb = sender as CheckBox; var items = cb. Tag as IEnumerable; PropertyInfo prop = null; foreach (var item in items) { if (prop == null) { var type = item.GetType(); var propname = cb. Content as string; prop = type.
GetProperty(propname); } prop. SetValue(item, cb. IsChecked, null); } }.
Thanks for the post. I'll give it a try. I'm assuming DPData is synomymous with AveragedParameters that I called on in my original post.
– KyleLib May 11 '11 at 19:43 Just any kind of ItemsSource, yes. – H.B. May 11 '11 at 19:47 your post gave me some ideas. Since I'm using MVVM my end solution used MultiBinding.
I'll post my solution shortly. – KyleLib May 12 '11 at 16:59.
If you want to stick with MVVM approach I would suggest to go for binding approach rather than event handling approach as MVVM avoids writing code in code behind file. One way could be to simply bind two bool properties in view model with IsChecked Property of both checkboxes. Based on the change notification using INotifyPropetyChanged, you can iterate through your itemssource i.e.
AveragingParameters and change either CalMin or CalcAverage.
2 That's a common misconception of MVVM. MVVM doesn't dictate no code behind. What it does dictate is no business logic in your code behind.
I've heard it put this way: "CodeBehind should be the domain of the designer only". In other words, if you have code behind make sure it is view specific and no business logic. Otherwise you will end up with a nasty mix of view logic in your ViewModel - just as bad as putting business logic in your view.
– SRM May 11 '11 at 20:13 Thanks for the posts btw. I actually solved this problem using mult-binding. I'll include it as a solution shortly.
– KyleLib May 12 '11 at 15:53 I believe @SRM is correct regarding MVVM and codebehind. Following those guidelines will let you easily support other views if you need support for say WPF and Silverlight. As for your proposed solution, I wanted to avoid binding to multiple properties if I could.
Reason being, the next iteration of this code will likely be a user control that allows for the ability to make the number of columns dynamic. Today I have 4 columns of checkboxes. Future consumers may require a different view model and need more or less columns.
– KyleLib May 12 '11 at 16:27.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.