In order to get the best performance optimizations out of the XamDataGrid, I'm told I should use the default RecordContainerGenerationMode (Recycle).
However, one reason I had been using another generation mode (PreLoad) is because it gave me well-defined and predictable behavior where SaveCustomizations() and LoadCustomizations() is concerned.
Those methods always behave well with a PreLoad XamDataGrid, as long as the grid has been loaded, and layouts have been initialized, and the dispatcher queue is relatively empty. However, now that I'm trying to use "Recycle" again (thereby fixing many general-purpose layout performance issues) I'm struggling with the customization problems once again (the ones that had sent be over to "PreLoad").
Attached is an example. Note that I do customizations as a very LAST step after:
I did this as the very LAST step, to try to give customizations the best possible chance to work properly but they still don't. Note that the customizations are applied correctly to the FieldLayout in view (TopMovie), but another FieldLayout that is *not* in view yet is totally misconfigured (OtherMovie). Both of them should have the same customizations applied.
In order for both FieldLayouts to be customized properly, change the RecordContainerGenerationMode to "PreLoad". You will see that there are three fields being customized ("MovableFields"). One "MoveableField" is hidden and the other two have their column positions exchanged.
Please let me know if there are questions about how the attached example is intended to behave.
After considering this a bit more last night, I'll probably need to report a support case.
As far as I can tell, there isn't any valid reason why one layout should behave one way and the other layout a different way, despite getting the same field layout customizations. It might be understandable if one of the FieldLayouts had not yet been fully "initialized" but, insofar as both of the FieldLayouts are concerned, they already fired all their initialization events and are "good-to-go" - or at least they don't have any other public fields, events or property changes which say otherwise. The only difference between the two FieldLayouts in my sample (ie between one that was customized properly and the one that was not) is the movement of the vertical scrollbar. The scrollbar has not yet made both of them visible. That seems pretty fragile.
I'm eager to hear if anyone on this forum has any workaround. Ideally I'd be able to keep the "Recycle" mode. But I'm hoping there is a way to trigger a one-time "PreLoad" , in a manual way, when the xamdatagrid is first constructed. That should allow my customizations to (properly) take effect.
Any help or feedback would be appreciated. I'm hoping to migrate a particular XamDataGrid from the "PreLoad" to "Recycle" mode, and push it to production within three weeks or so. It will be a welcome change, since the "Recycle" mode is a lot more responsive to user interaction with editable data.
Hello,
Thank you for the details and sample application you have provided.
At the time you return the custom customizations XDocument to XamDataGrid the FieldLayout that is out of the view is not created and this is the reason that the changes are not applied. In order to load customizations for layout that is not created yet, you should modify the customizations logic you are using. In your MoveField method you are adding column attribute only for specific Fields, so the XamDataGrid does not know how to arrange the fields that are not visible.
You can modify the DataGridColumnLogic.MoveColumn method to add default attribute values(column, row, etc.) for all of the fields, so the XamDataGrid can load the field positions correctly:
// Get the two fields (one as desired, one to which we will apply changes.)XElement LoopApplyField = FindFieldInLayout(CurrentLayoutElement, LoopDesiredFieldName);if (p_ColumnName != LoopDesiredFieldName ){ if (LoopApplyField.Attribute("column") == null) { if (p_ColumnPos == defaultPosition) defaultPosition++; // Get the two fields (one as desired, one to which we will apply changes.) LoopApplyField = FindFieldInLayout(CurrentLayoutElement, LoopDesiredFieldName); LoopApplyField.SetAttributeValue("column", defaultPosition.ToString()); LoopApplyField.SetAttributeValue("row", "0"); LoopApplyField.SetAttributeValue("rowSpan", "1"); LoopApplyField.SetAttributeValue("columnSpan", "1"); LoopApplyField.SetAttributeValue("isCollapsedInLayout", "false"); defaultPosition++; }}else{ oldPosition = defaultPosition; LoopApplyField = FindFieldInLayout(CurrentLayoutElement, LoopDesiredFieldName); // Set the attribute to the desired value LoopApplyField.SetAttributeValue("column", p_ColumnPos.ToString()); LoopApplyField.SetAttributeValue("row", "0"); LoopApplyField.SetAttributeValue("rowSpan", "1"); LoopApplyField.SetAttributeValue("columnSpan", "1"); LoopApplyField.SetAttributeValue("isCollapsedInLayout", "false"); defaultPosition = oldPosition;}
if (LoopApplyField.Attribute("column") == null) { if (p_ColumnPos == defaultPosition) defaultPosition++; // Get the two fields (one as desired, one to which we will apply changes.) LoopApplyField = FindFieldInLayout(CurrentLayoutElement, LoopDesiredFieldName);
LoopApplyField.SetAttributeValue("column", defaultPosition.ToString()); LoopApplyField.SetAttributeValue("row", "0"); LoopApplyField.SetAttributeValue("rowSpan", "1"); LoopApplyField.SetAttributeValue("columnSpan", "1"); LoopApplyField.SetAttributeValue("isCollapsedInLayout", "false"); defaultPosition++; }}else{ oldPosition = defaultPosition; LoopApplyField = FindFieldInLayout(CurrentLayoutElement, LoopDesiredFieldName); // Set the attribute to the desired value LoopApplyField.SetAttributeValue("column", p_ColumnPos.ToString()); LoopApplyField.SetAttributeValue("row", "0"); LoopApplyField.SetAttributeValue("rowSpan", "1"); LoopApplyField.SetAttributeValue("columnSpan", "1"); LoopApplyField.SetAttributeValue("isCollapsedInLayout", "false");
defaultPosition = oldPosition;}
I have modified the project you have attached to illustrate the suggested approach.
Please let me know if you require any further assistance regarding this matter.
Sincerely, ZhivkoEntry Level Software Developer
Here is the main issue: Only certain fields are customizable. IE the ones named "Movable" or whatever. Think of this as a "delta" operation that keeps everything exactly as-is except for columns that are specifically identified.
All other columns must retain whatever default behavior is given to them by (1) the XamDataGrid implementation, as developed by Infragistics, and (2) by the current XAML markup that defines our data grid.
Given we want "default" behavior for layouts and columns as indicated by (1) and (2) above, it seems like a very bad idea for me to be "whacking" on all columns, whether "Movable" or not, in a manual/programmatic way as you are doing. (Thereby hard-coding all sorts of things that should be coming from markup like the "row", "rowSpan", "columnSpan", etc.) It will be a fragile solution that regularly breaks if/when the implementation of the XamDataGrid changes and as our XAML markup changes over time.
The theory behind the current design is that we extract the state of the grid, given (1) and (2), and we only adjust only the pieces we care about before sending the back the customizations. Note that it starts with a call to "SaveCustomizations()" and ends with "LoadCustomizations()". Your grid should be able to support the Loading of its own Saved customizations.
Moving forward, you had mentioned a timing issue (grid "not created yet"). Please tell me what event or property you are using to determine this.
While I understand your workaround, I'd prefer a slightly different one that preserves more of the "default" behaviors of the XamDataGrid, given (1) and (2). Can you please tell me what happens in a "PreLoad" grid that triggers all the layouts to be "created" even the ones that are "out of view"? I'm hoping that I can preemptively force that same thing to happen in a "Recycle" grid at a pre-determined moment of time, right before the customization logic is performed.
Hello David,
I have reviewed your post and asked a few other developers to look into this scenario. We are working on your issue in order to provide you the best solution.
I will follow up with our findings as soon as we are ready with our investigation.
Thank you for your patience and understanding.
We have shipped out a new service release where your issue is resolved. To download the latest service release follow these steps:
1. View My Keys and Downloads: https://ko.infragistics.com/my-account/keys-and-downloads2. Log in to the Infragistics web site if you are not already logged in.3. Select the product you would like to download a service release for.4. Select the “Service Releases” tab.5. Select the download (e.g. Infragistics Xamarin.Forms 2015 - Service Release)
Sincerely, Zhivko Entry Level Software Developer
David,
Thank you for your reply. The issue has been since fixed internally and is now currently awaiting test. We will provide more details as they become available.
Thanks for getting them involved. I don't know if you read it in an earlier post but I had also opened a support case, simply so I can tell the stakeholders that I had opened a support case (CAS-177679-F0K1C7) .
I'm eager to get a good work-around as soon as possible. My original guess was that this would take three weeks or so. Please let me know if you think things will move slower than that.
Thanks, David
To ensure that your issue will receive attention, I have logged this behavior in our internal tracking system with a Development ID of 226687. The next step will be for a developer to review my investigation and confirm my findings or to offer a fix, or other resolution.
Please let me know if you need more information.