We are using WPF with the MVVM pattern. When a button on the View is clicked on by the user, the command is bound to an item in the ViewModel for handling it. This successfully adds a new line to the bottom of the master grid (if the currently selected line is the last), then adds a child line to the selected row. Finally it calls a Mediator.Instance.NotifyColleagues (Cinch) in order to basically signal an event that is picked up in the View's code behind. I have tried several variations but am unable to get the second column of the first child row to go into edit mode. I did try IsInEditMode = true and BeginEdit().
Of great concern is the following lines where I expect to get all of the RadGridViews contained within the master, as well as all of the rows.
Instead, I get null for grids and only 1 for rows??? I was expecting something like 8 for grids count and 26 for rows count. I am aware that the children have a completely separate RadGridView than the master, however, I am explicitly indicating grid1 (the master RadGridView) in this case.
The code behind message sink is as follows (and using a breakpoint - it clearly gets hit at the expected time too).
If it helps, the method in the ViewModel looks as follows:
And without boring everyone to tears the two RadGridViews in the XAML (one master and one child template for hierarchy) are as follows:
grid1 - the master RadGridView
gridChildren - the HierarchyChildTemplate RadGridView
Of course, there are lots of event handlers declared in the Constructor and so on but I am not including the entire solution just enough to try and assist anyone with helping to solve this problem. We were trying to keep our code behind to a minimum but I fail to see how I can do things like set the focus of a row in a RadGridView and set a particular cell to be in edit mode from the ViewModel without the ViewModel having some sort of awareness of the View (presentation layer) which it should not. If I have missed something here and am heading down the wrong path then kindly enlighten me. :)
Thanks,
Rob
Of great concern is the following lines where I expect to get all of the RadGridViews contained within the master, as well as all of the rows.
var grids = grid1.ChildrenOfType<RadGridView>();var rows = grid1.ChildrenOfType<GridViewRow>();Instead, I get null for grids and only 1 for rows??? I was expecting something like 8 for grids count and 26 for rows count. I am aware that the children have a completely separate RadGridView than the master, however, I am explicitly indicating grid1 (the master RadGridView) in this case.
The code behind message sink is as follows (and using a breakpoint - it clearly gets hit at the expected time too).
[MediatorMessageSink(MediatorConstants.Cashbook_ChildStatementLineFocus)] private void Cashbook_ChildStatementLineFocusMessageSink(int currentRowIndex) { if (grid1.ItemsSource != null) { grid1.ExpandHierarchyItem(this.grid1.Items[currentRowIndex]); Dispatcher.BeginInvoke((Action)delegate { var grids = grid1.ChildrenOfType<RadGridView>(); var rows = grid1.ChildrenOfType<GridViewRow>(); foreach (var row in rows) { if (grid1.SelectedItem == this.grid1.Items[currentRowIndex]) { var child = row.ChildrenOfType<RadGridView>().FirstOrDefault(); child.SelectedItem = child.Items[0]; var column = child.Columns[1]; var cellToEdit = new GridViewCellInfo(child.SelectedItem, column, child); child.CurrentCellInfo = cellToEdit; child.BeginEdit(); } } }); //RadGridView childGrid = this.grid1.ChildrenOfType<RadGridView>().FirstOrDefault(x => ((DOFinBankStatementTran)x.ParentRow.DataContext).BankStatementTranID == ((DOFinBankStatementTran)this.grid1.CurrentItem).BankStatementTranID); //if (childGrid != null) //{ // var item = childGrid.Items[0]; // var column = this.grid1.Columns[1]; // var cellToEdit = new GridViewCellInfo(item, column, childGrid); // childGrid.CurrentCellInfo = cellToEdit; // childGrid.BeginEdit(); //} } }If it helps, the method in the ViewModel looks as follows:
private void ExecuteDissectionCommand() { try { DOFinBankStatementTran currentLine = SelectedStatementLine; if (currentLine == StatementLinesSource.Last()) { AddNewLineCommand.Execute(true); } if (currentLine.Children == null) { currentLine.Children = new List<DOFinBankStatementTran>(); DOFinBankStatementTran line = CurrentClientHelper.ClientFinancial.CreateBankStatementTran(currentLine.GLBankAccount); line.ParentStatementTranID = currentLine.BankStatementTranID; line.GLBankAccountID = currentLine.GLBankAccountID; line.GLBankAccount = currentLine.GLBankAccount; line.HasChildren = false; line.ImageForIsEditable = currentLine.ImageForIsEditable; line.IsActive = true; line.IsDeleted = false; line.IsPosted = false; line.IsReconciled = false; currentLine.Children.Add(line); currentLine.HasChildren = true; } int i = StatementLinesSource.IndexOf(currentLine); StatementLinesSource.RemoveAt(i); StatementLinesSource.Insert(i, currentLine); Mediator.Instance.NotifyColleagues<int>(MediatorConstants.Cashbook_ChildStatementLineFocus, i); } catch (Exception ex) { //check if exception type is global exception and throw ExceptionHelper.CheckExceptionType(ex, typeof(GlobalException)); _messageBoxService.ShowError("DissectionCommand Error:"+ex.Message); CurrentClientHelper.ClientAudit.LogException(ex, EventCategory.Client); } }And without boring everyone to tears the two RadGridViews in the XAML (one master and one child template for hierarchy) are as follows:
grid1 - the master RadGridView
<telerik:RadGridView x:Name="grid1" Grid.Row="1" Grid.Column="0" ShowGroupPanel="False" AutoGenerateColumns="False" RowIndicatorVisibility="Collapsed" IsReadOnly="False" CanUserInsertRows="False" EditTriggers="CellClick" RowLoaded="grid1_RowLoaded" ItemsSource="{Binding StatementLinesSource,Mode=TwoWay}" SelectedItem="{Binding SelectedStatementLine, Mode=TwoWay}" BeginningEdit="grid1_BeginningEdit" IsSynchronizedWithCurrentItem="False" aps:SingleEventCommand.RoutedEventName="CellEditEnded" aps:SingleEventCommand.CommandParameter="{Binding ElementName=grid1, Path=CurrentCell.Column.UniqueName}" aps:SingleEventCommand.TheCommandToRun="{Binding CellEditEndedCommand}" abs:RadGridViewKeyboardBehaviour.IsEnabled="True" abs:RadGridViewKeyboardBehaviour.EnterDirection="MoveNext" ScrollViewer.HorizontalScrollBarVisibility="Auto" EnableColumnVirtualization="True" EnableRowVirtualization="True" UseLayoutRounding="False" >gridChildren - the HierarchyChildTemplate RadGridView
<telerik:RadGridView x:Name="gridChildren" CanUserFreezeColumns="False" AutoGenerateColumns="False" ItemsSource="{Binding Children}" ShowGroupPanel="False" CanUserInsertRows="True" SelectionChanged="gridChildren_SelectionChanged" RowEditEnded="gridChildren_RowEditEnded" RowValidating="gridChildren_RowValidating" RowLoaded="gridChildren_RowLoaded" abs:RadGridViewKeyboardBehaviour.IsEnabled="True" abs:RadGridViewKeyboardBehaviour.EnterDirection="MoveNext" EditTriggers="CellClick" IsTabStop="True" DataLoaded="gridChildren_DataLoaded" >Of course, there are lots of event handlers declared in the Constructor and so on but I am not including the entire solution just enough to try and assist anyone with helping to solve this problem. We were trying to keep our code behind to a minimum but I fail to see how I can do things like set the focus of a row in a RadGridView and set a particular cell to be in edit mode from the ViewModel without the ViewModel having some sort of awareness of the View (presentation layer) which it should not. If I have missed something here and am heading down the wrong path then kindly enlighten me. :)
Thanks,
Rob