Hello,
My grid provides the AddNew record, but additionally I want the user to be able to create a new record by a keyboard shortcut and a ribbon button.In the code behind the following code is executed when the user initiates this command:
grid.ExecuteCommand(DataPresenterCommands.EndEditModeAndCommitRecord);grid.ActiveRecord = grid.RecordManager.CurrentAddRecord;grid.ExecuteCommand(DataPresenterCommands.CellFirstInRecord);grid.ExecuteCommand(DataPresenterCommands.StartEditMode);
This commits and current editing, activates the AddNewRecord line and puts the first cell in edit mode.So far - so good.
Unfortunately the underlying business object is not initialized by this action.Only when the user starts typing, the object is created and initialized.How can I bring the grid to do this initializing on its own?
Thank you for any hint.
BTW: how can I paste code with syntax highlighting?I even tried the paste-from-word thing, but after inserting the coloring and formatting is gone...
I know this is an old post but here is what I do with Infragistics WPF 22.1
private void btnAdd_Click(object sender, RoutedEventArgs e) { xamDataGrid1.FieldLayoutSettings.AllowAddNew = true; Dispatcher.BeginInvoke(new Action(() => {
// Force the creation of the addRecord and enter a value in the first field so that the default values of the underlying object are displayedCellValuePresenter.FromCell(xamDataGrid1.RecordManager.CurrentAddRecord.Cells[0]).Editor.StartEditMode(); CellValuePresenter.FromCell(xamDataGrid1.RecordManager.CurrentAddRecord.Cells[0]).Editor.Value = 0;
// Move to the next cell to exit the edition mode xamDataGrid1.ExecuteCommand(DataPresenterCommands.CellRight); xamDataGrid1.ExecuteCommand(DataPresenterCommands.CellLeft); }), DispatcherPriority.Background, null); }
Hi Community,
because my sample code above uses some of my own helper classes,you will not be able to use it.
I gained a lot of help from this forum so far,so I decided to create a sample application which demonstrates the instantly initializing AddNew record.
To even make it more useful,the complete logic is encapsulated in an interactivity behavior.
@Rob:Could you try to run this sample?If it works, you can mark this post as veryfied answer :-)
Hello J_Feuerstein,
This is pretty much the only way that I can think of to get the functionality that you are looking for. Grabbing the editor and setting a value into it will cause the underlying data to be created. This is basically the approach I would end up suggesting. And you even have the code handle different value types which is awesome. This should prove useful to the community.
I coded the following hack to get the wanted behavior.It is ugly, but works. Maybe you have a better suggestion...
private void AddNewTimeBookingEntry() { var grid = TimeBookingDataGrid; if (grid.RecordManager.CurrentAddRecord == grid.ActiveRecord) return; // commit any current edit action and set the active record to the AddNew row grid.ExecuteCommand(DataPresenterCommands.EndEditModeAndCommitRecord); grid.ActiveRecord = grid.RecordManager.CurrentAddRecord; var record = grid.ActiveRecord; if (record == null) return; // get the DataRecord of the AddNewRow var dataRecord = record as DataRecord; if (dataRecord == null || !dataRecord.IsAddRecord) return; // only proceed if there is not DataItem assocciated so far if (dataRecord.DataItem != null) return; // get the first ValueEditor from the available cells // which has a simply constructable value type var valueEditor = dataRecord.Cells .Select(CellValuePresenter.FromCell) .Where(x => x != null) .Select(x => x.Editor) .FirstOrDefault(x => x.ValueType.IsPrimitive || x.ValueType.IsValueType); if (valueEditor == null) return; // if the value type is nullable, fetch the underlying type instead var valueType = valueEditor.ValueType.IsNullable() ? Nullable.GetUnderlyingType(valueEditor.ValueType) : valueEditor.ValueType; // create a dummy instance of the value type var initialValue = Activator.CreateInstance(valueType); // simulate input of the dummy value and cancel it again // this forces the grid to create the underlying data instance. valueEditor.StartEditMode(); valueEditor.Value = initialValue; valueEditor.EndEditMode(acceptChanges: false, force: true); // get the first field which has a TabStop var orderedFields = TimeBookingDataGrid.FieldLayouts.First() .Fields.OrderBy(x => x.ActualPosition.Column); var firstTabStopField = orderedFields.FirstOrDefault(x => (bool)x.GetValue(FieldTabStopBehavior.EnabledProperty)); // get the cell from the current record according to the field // and activate it var firstTabStopCell = dataRecord.Cells.FirstOrDefault(x => x.Field.Equals(firstTabStopField)); grid.ActiveCell = firstTabStopCell; // start edit mode for the user grid.ExecuteCommand(DataPresenterCommands.StartEditMode); }
private void AddNewTimeBookingEntry() { var grid = TimeBookingDataGrid; if (grid.RecordManager.CurrentAddRecord == grid.ActiveRecord) return;
// commit any current edit action and set the active record to the AddNew row grid.ExecuteCommand(DataPresenterCommands.EndEditModeAndCommitRecord); grid.ActiveRecord = grid.RecordManager.CurrentAddRecord;
var record = grid.ActiveRecord; if (record == null) return;
// get the DataRecord of the AddNewRow var dataRecord = record as DataRecord; if (dataRecord == null || !dataRecord.IsAddRecord) return;
// only proceed if there is not DataItem assocciated so far if (dataRecord.DataItem != null) return;
// get the first ValueEditor from the available cells // which has a simply constructable value type var valueEditor = dataRecord.Cells .Select(CellValuePresenter.FromCell) .Where(x => x != null) .Select(x => x.Editor) .FirstOrDefault(x => x.ValueType.IsPrimitive || x.ValueType.IsValueType); if (valueEditor == null) return;
// if the value type is nullable, fetch the underlying type instead var valueType = valueEditor.ValueType.IsNullable() ? Nullable.GetUnderlyingType(valueEditor.ValueType) : valueEditor.ValueType; // create a dummy instance of the value type var initialValue = Activator.CreateInstance(valueType);
// simulate input of the dummy value and cancel it again // this forces the grid to create the underlying data instance. valueEditor.StartEditMode(); valueEditor.Value = initialValue; valueEditor.EndEditMode(acceptChanges: false, force: true);
// get the first field which has a TabStop var orderedFields = TimeBookingDataGrid.FieldLayouts.First() .Fields.OrderBy(x => x.ActualPosition.Column); var firstTabStopField = orderedFields.FirstOrDefault(x => (bool)x.GetValue(FieldTabStopBehavior.EnabledProperty)); // get the cell from the current record according to the field // and activate it var firstTabStopCell = dataRecord.Cells.FirstOrDefault(x => x.Field.Equals(firstTabStopField)); grid.ActiveCell = firstTabStopCell;
// start edit mode for the user grid.ExecuteCommand(DataPresenterCommands.StartEditMode); }
Hello Rob,
thank you for response.The default behavior may be suitable in many cases.But my data object is initialized with default values on each field.When the user starts input in any cell, the default value for this cell is instantly overwritten.
Further I want to use the built-in AddNewRow feature.When I go the way you suggest by adding the new record to the vievmodel collection,it is a row like any other. For example canceling edit will not remove it automatically,and it is not located where the empty AddNewRow is.
My goal is that even when the user only clicks on any cell of the empty AddNewRow,instantly the data object is instantiated and the clicked column is in edit mode with the default data of this column.But it has to stay in add-new mode, not commited in any way.
Hope you can give me a hint on this.Thanks a lot.