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