tags:

views:

41

answers:

1

Hello..

i will try to be clear.. here i am working on a datagrid. in datagrid one column is editable as i am passing DataGridTextColumn to it and holding the data when users enter data into it and writing back to database. i am saving to database using datagrid_celleditending event also i am using the datagridcelleditendingeventargs to do this. This is done and working fine. i have added new functionality such that instead of entering data in datagrid, users will enter in one textbox which will be given on top of datagrid and the on entering data in to cell i am synchronizing it with datagrid cell and i can see data in it (just like excel having one big bar on top and you can write the data there and also see in datagrid). i am doing this by using textbox_keyup event. now i wanted to fire the event of datagrid_celleditending event args. i tried using routed event implementation but its not working.

hope i am not confusing, please help..

Here is a chunk of code..

private void dataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
    {
        DataRowView rowView = e.Row.Item as DataRowView;
        rowBeingEdited = rowView;
        //Here my logic to write to database will come
        .........
        .........      
   }

//The above event is working fine when i change in datagrid now i wanted to fire this when i enter data in the text box which is not a part of datagrid

   private void tb_Comments_KeyUp(object sender, KeyEventArgs e)
    {
        if (rowBeingEdited != null)
        {
            rowBeingEdited.Row["Comments"] = tb_Comments.Text;
           //here i wanted to go to the above event and fire it..how can i do it??
        }

     }
A: 

What's your SelectionUnit for the DataGrid set to? This works for SelectionUnit="CellOrRowHeader", otherwise some things must be changed a bit at the end. Anyway, the following code puts a cell in edit-mode and then commits it which fires the CellEditEnding event.

public void EnterCellEditEndingForCell(DataGridColumn column, DataRowView dataRowView)
{
    int selectedRowIndex = -1;
    // c_dataGrid.Items.IndexOf(dataRowView)
    // sometimes break and return -1.
    for (int i = 0; i < c_dataGrid.Items.Count; i++)
    {
        DataRowView rowView = c_dataGrid.Items[i] as DataRowView;
        if (rowView == dataRowView)
        {
            selectedRowIndex = i;
            break;
        }
    }
    int selectedColumnIndex = c_dataGrid.Columns.IndexOf(column);
    if (selectedRowIndex >= 0 && selectedColumnIndex >= 0)
    {
        DataGridCell dataGridCell = DataGridHelper.GetCell(c_dataGrid, selectedRowIndex, selectedColumnIndex);
        if (dataGridCell == null)
        {
            c_dataGrid.ScrollIntoView(dataRowView);
            dataGridCell = DataGridHelper.GetCell(c_dataGrid, selectedRowIndex, selectedColumnIndex);
        }
        dataGridCell.BringIntoView();
        dataGridCell.Focus();
        c_dataGrid.SelectedCells.Clear();
        DataGridCellInfo info = new DataGridCellInfo(dataGridCell);
        c_dataGrid.SelectedCells.Add(info);
        c_dataGrid.BeginEdit();
        c_dataGrid.CommitEdit(DataGridEditingUnit.Cell, true);
    }
}

DataGridHelper.cs if you don't have an implementation of it

static class DataGridHelper
{
    static T GetVisualChild<T>(Visual parent) where T : Visual
    {
        T child = default(T);
        int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < numVisuals; i++)
        {
            Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
            child = v as T;
            if (child == null)
            {
                child = GetVisualChild<T>(v);
            }
            if (child != null)
            {
                break;
            }
        }
        return child;
    }

    static public DataGridCell GetCell(DataGrid dg, int row, int column)
    {
        DataGridRow rowContainer = GetRow(dg, row);

        if (rowContainer != null)
        {
            DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);

            // try to get the cell but it may possibly be virtualized
            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            if (cell == null)
            {
                // now try to bring into view and retreive the cell
                dg.ScrollIntoView(rowContainer, dg.Columns[column]);
                cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            }
            return cell;
        }
        return null;
    }


    static public DataGridRow GetRow(DataGrid dg, int index)
    {
        DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(index);
        if (row == null)
        {
            // may be virtualized, bring into view and try again
            dg.ScrollIntoView(dg.Items[index]);
            row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(index);
        }
        return row;
    }
}

UPDATE If you have only one cell selected (which sounds like the case) than you can do this.

private void tb_Comments_KeyUp(object sender, KeyEventArgs e) 
{ 
    if (rowBeingEdited != null) 
    { 
        rowBeingEdited.Row["Comments"] = tb_Comments.Text; 
        DataGridColumn columnBeingEdited= GetActiveDataGridColumn();
        EnterCellEditEndingForCell(columnBeingEdited, rowBeingEdited);
    } 
 } 

private DataGridColumn GetActiveDataGridColumn()
{
    if (c_dataGrid.SelectedCells.Count != 1)
    {
        return null;
    }
    return c_dataGrid.SelectedCells[0].Column;
}
Meleak
I created a helper class and introduced the method EnterCellEditEndingForCell in my code.. but do i need to call this from Xaml or from Tb_Keyup method?? i didnot clearly understand when you meant selection unit in datagrid.. when i enter data in the textbox, its writing in datagrid using "rowBeingEdited.Row["Comments"] = tb_Comments.Text;" Thank you so much for you help..
prem
Also i forgot to mention that i am using WPF, but the helper file which you created works for windows forms.. can i use the same for WPF also?? sorry i am a starter in C# coding and trying to learn the things..thanks for the help once again..
prem
When you setup the DataGrid in Xaml, what is SelectionUnit set to? It can be SelectionUnit="CellOrRowHeader", SelectionUnit="Cell" or SelectionUnit="FullRow". This will change how SelectionCells, SelectedItem etc. behaves. Yes, the helper class is WPF and you should call this method in code. I Updated my example
Meleak
Yes the selection unit ="CellOrRowHeader" only. But i have another basic doubt..i wanted to pass column contains header "Comments" to the EnterCellEditEndingForCell method, but it accepts DataGridColumn , how can i declare and pass "Comments" to the method?? Thansk for helping me!!!
prem
Updated my example, try it out
Meleak
Working grea Meleak...Thanks for you patience and help..thanks a lot..
prem