I have two columns in my data source that is editable and is a boolean value. My data object implement INotifyPropertyChanged. Two questions:
1. When I initially run the app, all checkboxes are kinda grayed out, in some intermediate state, even though my data objects certain have values fro those boolean properties. How can I make sure they properly load?
2. The value of one bool depends on the other. The two properties cannot be true, but any other combination is possible. To this end, my data object has logic so if: valA is set to true, if valB is true, property valB is set to false and vice-versa. The issue is that the actual setter is not called by the Check Editor until the checkbox is unfocused. What's my best way to go around this? Should I attach custom event handlers to valuechanged? Should I create an unbound column and create a control template that displays my own custom checkbox with custom handlers?
Thanks,
-Szymon
Hello Szymon,
Are you binding the check editor directly to your CLR object (which has INotifyPropertyChanged) or to a DependencyProperty? When the data changes, the INotifyPropertyChanged event should trigger the data to update in the UI and if using a DependencyProperty you get the same behavior. If you could post or attach some code or a sample project which demonstrates the problem, I might see what is going on and offer a solution.
Ok. I have attached a project that replicates both issues I am seeing. So basically I'm not doing any of the binding myself; I let the grid do it for me. In my actual xaml, I define my own field, editor types and edit as, but the behavior is exactly the same as allowing the grid to create the fields on its own.
I see the issue you are talking about. The internal binding UpdateSourceTrigger needs to be changed from the default "LostFocus" to "PropertyChanged". I will look into how to do this and post the solution.
For now, I'm using the following workaround:
1. Add the following Field settings to my boolean fields:
<igDP:Field.Settings> <igDP:FieldSettings AllowEdit="True" EditAsType="{x:Type sys:Boolean}" EditorType="{x:Type igEditors:XamCheckEditor}" LabelWidth="60" CellWidth="60"> <igDP:FieldSettings.EditorStyle> <Style TargetType="{x:Type igEditors:XamCheckEditor}"> <EventSetter Event="ValueChanged" Handler="HandleValueChangedAccept" /> </Style> </igDP:FieldSettings.EditorStyle> </igDP:FieldSettings> </igDP:Field.Settings>
and:
<igDP:Field.Settings> <igDP:FieldSettings AllowEdit="True" EditAsType="{x:Type sys:Boolean}" EditorType="{x:Type igEditors:XamCheckEditor}" LabelWidth="60" CellWidth="60" > <igDP:FieldSettings.EditorStyle> <Style TargetType="{x:Type igEditors:XamCheckEditor}"> <EventSetter Event="ValueChanged" Handler="HandleValueChangedRollback" /> </Style> </igDP:FieldSettings.EditorStyle> </igDP:FieldSettings> </igDP:Field.Settings>
I am hooking a handler to the ValueChanged event on the XamCheckEditor.
2. Implement the handling methods:
void HandleValueChangedAccept(object sender, RoutedPropertyChangedEventArgs<object> e) { bool newValue = (bool)e.NewValue; if (!newValue) return; DependencyObject o = Infragistics.Windows.Utilities.GetAncestorFromType(e.OriginalSource as DependencyObject, typeof(DataRecordCellArea), true); DataRecordCellArea dataRecord = o as DataRecordCellArea; if (dataRecord == null) return; DAO dao = dataRecord.Record.DataItem as DAO ; dao.Accept = (bool)e.NewValue; } void HandleValueChangedRollback(object sender, RoutedPropertyChangedEventArgs<object> e) { bool newValue = (bool)e.NewValue; if (!newValue) return; DependencyObject o = Infragistics.Windows.Utilities.GetAncestorFromType(e.OriginalSource as DependencyObject, typeof(DataRecordCellArea), true); DataRecordCellArea dataRecord = o as DataRecordCellArea; if (dataRecord == null) return; DAO dao = dataRecord.Record.DataItem as DAO ; dao .Rollback = (bool)e.NewValue; }
Notice that my logic dictates that two values cannot be set to true. My DAO setters handle this logic. But this creates an opportunity for an infinite loop. Since dao.Rollback may change the value of dao.Accept, the ValueChanged handlers for the checkboxes may keep on calling each other infinitely. For this purpose, I make sure that the handler doesn't do anything if the new value is false.
So this is a bit of a hackish way to do this, but it works. Chris, let me know if there's a more elegant way to do this using the UpdateSourceTrigger property of the internal binding.
I'm having same issues with bool type values I add to XamDataGrid. Here's the simple project I made with same thing.
Any updates on this topic ?
After spending time with this, it appears bool fields using xamCheckEditors only send change notifications after the checkEditor loses focus. Since there appears to be no way to override this behavior, I would consider this a defect. If you would send a report in, that would be great!
Online Form: http://devcenter.infragistics.com/Protected/SubmitSupportIssue.aspx
In the meanwhile, I was able to get your original code (the simpler version without any of the INotificationChanged code) to work. I am posting the code to show how I use FieldSettings to specify the layout of the fields including using a regular checkbox for the two bool fields.
Here is your original code-behind, untouched:
public Window1(){ InitializeComponent(); IList<DataObject> l = new List<DataObject>(); DataObject dataObj; dataObj = new DataObject(); dataObj.Id = Guid.NewGuid().ToString(); dataObj.Rollback = true; dataObj.Accept = false; l.Add(dataObj); dataObj = new DataObject(); dataObj.Id = Guid.NewGuid().ToString(); dataObj.Rollback = true; dataObj.Accept = true; l.Add(dataObj); dataObj = new DataObject(); dataObj.Id = Guid.NewGuid().ToString(); dataObj.Rollback = false; dataObj.Accept = false; l.Add(dataObj); myGrid.DataSource = l;}
<Window x:Class="WindowsApplication2.Window1"xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:x=http://schemas.microsoft.com/winfx/2006/xamlxmlns:igDP=http://infragistics.com/DataPresenter xmlns:sys="clr-namespace:System;assembly=mscorlib"Title="WindowsApplication2">
<Grid> <igDP:XamDataGrid Name="myGrid">
<igDP:XamDataGrid.Resources> <Style TargetType="{x:Type igDP:CellValuePresenter}" x:Key="BoolFieldOverride"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type igDP:CellValuePresenter}"> <CheckBox HorizontalAlignment="Center" VerticalAlignment="Center" IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"/> </ControlTemplate> </Setter.Value> </Setter> </Style> </igDP:XamDataGrid.Resources>
<igDP:XamDataGrid.FieldLayoutSettings> <igDP:FieldLayoutSettings AutoGenerateFields="False" /> </igDP:XamDataGrid.FieldLayoutSettings> <igDP:XamDataGrid.FieldLayouts> <igDP:FieldLayout> <igDP:FieldLayout.Fields>
<igDP:Field Name="Id" Label="GUID" > <igDP:Field.Settings> <igDP:FieldSettings CellMinWidth="250" CellWidth="250" /> </igDP:Field.Settings> </igDP:Field>
<igDP:Field Name="Rollback" Label="Option Rollback" > <igDP:Field.Settings> <igDP:FieldSettings CellMinWidth="50" CellWidth="50" CellValuePresenterStyle="{StaticResource BoolFieldOverride}"/> </igDP:Field.Settings> </igDP:Field>
<igDP:Field Name="Accept" Label="Option Accept" > <igDP:Field.Settings> <igDP:FieldSettings CellMinWidth="50" CellWidth="50" CellValuePresenterStyle="{StaticResource BoolFieldOverride}"/> </igDP:Field.Settings> </igDP:Field>
</igDP:FieldLayout.Fields> </igDP:FieldLayout> </igDP:XamDataGrid.FieldLayouts> </igDP:XamDataGrid></Grid></Window>
This works with your code-behind. Please let me know if I can help further.
I implemented this approach, because I did not see an alternative as of yet. The approach works great, with one exception.
I am defining my grids FieldSettings as follows:
<igDP:FieldSettings AllowEdit="True"
CellClickAction="EnterEditModeIfAllowed"
AllowGroupBy="False"/>
</igDP:XamDataGrid.FieldSettings>
I expected that when I entered the cell, either via Tab, or mouse click, that I enter the edit mode, however this does not happen when applying this style, and the user cannot edit the values of the checkbox with just the keyboard. Any way to force the cell to enter edit mode?
Thanks.