Checkboxes not updating as expected - wpf

I have a listbox bound to a list of business objects. The items in the listbox are formatted using an itemtemplate. The itemtemplate includes a checkbox bound to a boolean property of the business object. When I spin up the app, the bool prop on the object in the list is changed when I click the checkbox. so far, so good.
The dialog has "select all" and "clear all" buttons. When I click on of these buttons, the properties on the objects are changed but the checkbox does not update.
The code in the select all click event is. . .
For Each x As BusObj In _BusObjList
x.BlockIsInserted = True
Next
I can step through the code and watch the object properties change but the checkbox does not update. Any suggestions?
Thanks,

using twoway binding should help I guess
{Binding ..., Path=Text, Mode=TwoWay}
And yes, is BlockIsInserted property dependency? or implemented INotifyPropertyChanged?

I've encountered the same issue, even with the binding set to two-way and the view model representing the business object correctly implementing INotifyPropertyChanged. The (rather brute-force) solution I found was to NotifyChanged on the property representing the collection of business objects - this fixes the problem.

Related

Winforms ComboBox 2 way databinding only works 1 way

I have a combobox, and in the design view I have it databound to a bindingsource as follows:
this.itemTypeComboBox.DataBindings.Add(new System.Windows.Forms.Binding("SelectedValue", this.itemTypeContainerBindingSource, "ItemType", true));
this.itemTypeComboBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.itemTypeContainerBindingSource, "ItemType", true));
In the code behind in the load event I have the following:
// bind the combobox to the enum
this.itemTypeComboBox.DataSource = Enum.GetValues(typeof(OpticalItemType));
// bind a custom object to the datasource
this.itemTypeContainerBindingSource.DataSource = customObjectContainer;
The "customObjectContainer" is a single object that contains a property "ItemType" that is bound to the combobox, and all properties of the object use change notification through "INotifyPropertyChanged".
In my code behind, if I programmatically change the custom object, the changes are reflected in the combobox. However, if I change the combobox through the UI, the bindingsource, and hence the custom object do not reflect the changes.
Any ideas what I am doing wrong?
As it is a singular object, it cannot be to do with using BindingList etc.
UPDATE 1:
Ok, whenever I change the combobox through the UI, it never changes the underlying object, the setter is never hit for the property in the custom object. However, I have just noticed that if I tab off of the control, it then fires the setter, and changes the underlying object. Why would this be?
PROBLEM SOLVED:
It appears, the issue was with my binding. I added "DataSourceUpdateMode.OnPropertyChanged" to the bindings, and it works now!!
The issue was with my binding. I added "DataSourceUpdateMode.OnPropertyChanged" to the bindings, and it works now!!

Data validation on a ListBox in WPF

I have a ListBox bound to an ObservableCollection of type T - each ListBoxItem is a checkbox with IsChecked bound to a bool property in T. I want to validate the checked items in the ListBox so that at least one checkbox must be ticked - if none of the check boxes are ticked I want to show a red border (standard validation notification) around the ListBox.
How do I go about doing that? Can I use ValidatesOnDataErrors?
Implement IDataErrorInfo in the class that exposes the ObservableCollection<T> property and make the indexer return an error for that property's name if all of the objects in the collection have a value of false in their boolean property. Then use the DataErrorValidationRule in your binding's ValidationRules.
Your goal is to validate selected items of a ListBox: at least one selected item is required. First, there are different ways to handle the selection itself:
a) You can use the ListBox selection mechanism via ListBox.SelectedItem.
I guess, you can specifiy the binding as SelectedItem="{Binding SelectedThing, ValidatesOnNotifyDataErrors=True}" and WPF's regular validation works. Not sure, if this works well with multi-selection.
b) You can use ListBox.SelectedItems. Binding is not possible and needs to be faked via code behind event handler. Thus, WPF's validation cannot trigger here.
c) You use your own IsSelected property (or similar) per item, either explicitely bound to your viewmodel via CheckBox or implicitely via ListBoxItem.IsSelected (via ListBox.ItemContainerStyle).
From here you could create a bool IsValidSelection property in your viewmodel that updates whenever the selection changed. Or you can run validation rules on any of the resulting properties of your viewmodel (e.g. SelectedItems). However, you don't validate the bound ListBox.ItemSource itself! Therefore WPF's standard mechanisms don't work (the list box doesn't get a red border or whatever).
Workarounds
You can explicitely create error notifications by showing an otherwise invisible Label and binding its visibility to the above-mentioned bool IsValidSelection property. This is a very explicit way, not using WPF validation at all.
You can modify your INotifyDataErrorInfo (or similar) implementation to trigger errors on a different property name. This is not possible, if you use a generic ValidatableViewModel<T> (like me). I guess this was the intention of the other answer.

List<> Binding and button click using mvvm light

I am trying to use MVVM light to achieve something like this. I have the following scenario:
In my Model--I have set the properties like ActivityName,Image and there is a class constructor whose is accepting 2 parameters like name and image.
Im my DataAccess--I have set the database connection and implement the required method who will fetch the data from DB and I am storing in the List and returning the list to ViewModel.
In my ViewModel--I have created the list property who will return the list by calling the GetActivities() method that I have defined in the DataAccess.
Now my problem is I am not getting how to bind it in the View so that by clicking on a button it will display the list of activities with image. By clicking on some button a new window should open with the desired result. How to bind the above list and implement the button functionality using MVVM light.
Kindly help?
Thanks
First of all, use an ObservableCollection instead of a List as it would notify the view when property or collection changes.
Then set the DataContext of your view to the viewmodel. If you use MVVMLight View Class, then the DataContext would be automatically set. You've to just give the ViewModel Name there.
Then set the ItemsSource of the DataGrid like this <dg:DataGrid ItemsSource="{Binding YourListInViewModel}"/>
For handling click event you can use the Event-To-Command behaviour and write your logics in the Button's corresponding Command handler.
Bind to DataContext of the control

How to set a value in a ViewModel from binding?

Kind of an odd question- if I'm thinking of this the wrong way please let me know. I am using an infragistics dock manager, which manages tabs as well. So I can create a TabGroupPane, and then add multiple ContentPanes, each of which has its own tab.
In each content pane, I set my viewmodel:
<ContentPane>
<viewmodels:MyViewModelForTab1 />
</ContentPane>
So here's the problem- while using a mediator pattern for communication, my viewmodels have no idea if they are on the visible tab or not, so they are always working even if hidden. The TabGroupPane does have a SelectedTab property, as well as each ContentPane having an IsActive property.
So the question is how do I set that information in my ViewModel? Making my VM a dependency object seems like a bad idea since I already implement INotifyPropertyChanged. Using a CLR prop in my VM also doesnt work, since you cannot bind to it.
How can I get my VM to know if it is the datacontext of an active tab?
Thanks!
I would put an IsSelected property on my ViewModel and bind it to the TabItem's IsSelected dependency property.
This should allow you to hook into when it is updated and perform whatever you need. You don't need a mediator pattern here since you are communicatining from the View to the ViewModel.
Make sure your ViewModel is bound to the DataContext property of the view (specifically, that the Tab's DataContext is the ViewModel). The way you have it now, your ViewModel is the content of the element, not bound to the DataContext, as it should be:
<Tab.Resources>
<viewmodels:MyViewModelForTab1 x:Key="Tab1ViewModel" />
</Tab.Resources>
<ContentPane DataContext="{StaticResource Tab1ViewModel}" />
Or something like that...
I don't know the Infragistics model, so my apologies if this is inapposite, but here's how I implement this with regular items controls - tab control, list box, whatever.
Create a container view model class that includes an observable collection of items and exposes a SelectedItem property. Make the container class the data context of the items control. Bind the items control's SelectedItem property to the container class's.
Hook the item objects up to the PropertyChanged event of the container. So now when the selected item in the UI changes, the container view model notifies all of the items that SelectedItem has changed. Each item object's event handler can determine for itself whether or not it's now the selected item.
The item objects thus don't know any implementation details of the UI - you can unit test your classes outside of a UI and the logic will still work correctly.

BindableAttribute, Combobox, Selectedvalue property - WinForms

I am deriving from combobox (WinForms) and am providing a new implementation for the Selectedvalue property.
It works fine as is, but any change to the selectedvalue property is not updating other controls bound to the same "binding context" to change their values accordingly.
I did try adding the BindableAttribute(true) to the property, but still it does nottrigger the change in value to the other linked controls.
The control's DataBindings.add(...) is all set up. And other controls are also bound to the same data filed on the same datasource.
Any ideas what i am doing wrong.
Have you called your base class' implementation of overridden methods? It's possible that failing to call the base class implementation is accidentally circumventing the code that fires various event plumbing.

Resources