none
Deleted values are replaced automatically when user presses tab in Datagrid

    Question

  • I have a WPF application which is using the WPF DataGrid.It is working with  anonymous behaviour in the following scenerio.

    We entered text in the horizontal cells(A1,B1,C1,D1.....)

    Selected all the cells in which data is entered and clicked on delete button in the keyboard. all values are deleted.Then,selected the first cell(A1) and entered some text and clicked on tab key continuously. Then,Deleted data are showing in the cells upon pressing  tab key in the respective cells. Any solutions and suggestions  related to this are welcome.

    Thanks in advance.

     

     

    Monday, October 18, 2010 11:47 AM

All replies

  • Hi Naga bushan,

    Could you post some code snippets for us? It would appreciated if you could supply a small ready-to-run demo to show exact scenario you are encountering?

    Looking forward to your update :)

     

    Best regards,

    Yves


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
    Tuesday, October 19, 2010 12:22 PM
    Moderator
  • Hi Yves,

    This is the Datagrid which we are using in our application,which is having following events and properties.

    <DataGrid Grid.Row="1" Grid.Column="0" AutoGenerateColumns="True" Height="340" HorizontalAlignment="Center" Margin="46,12,0,0" Name="dataGrid1" 
       VerticalAlignment="Top" Width="726" ItemsSource="{Binding}" 
       KeyUp="Grid_KeyUp" MouseWheel="dataGrid1_MouseWheel"
       AllowDrop="True" Drop="Grid_Drop" SelectionMode="Extended" 
       MouseLeftButtonUp="Grid_MouseLeftButtonUp" dragDrop:RadDragAndDropManager.AllowDrop="True" 
       PreviewKeyUp="dataGrid1_PreviewKeyUp" PreviewKeyDown="dataGrid1_PreviewKeyDown" SelectionUnit="Cell" 
       LoadingRowDetails="dataGrid1_LoadingRowDetails" CanUserSortColumns="False" CanUserAddRows="False" 
       AutoGeneratingColumn="dataGrid1_AutoGeneratingColumn" CanUserReorderColumns="True" HorizontalGridLinesBrush="#FF616189"
       VerticalGridLinesBrush="#FF616189" AutoGeneratedColumns="dataGrid1_AutoGeneratedColumns" 
       GotFocus="dataGrid1_GotFocus" SourceUpdated="dataGrid1_SourceUpdated" LoadingRow="dataGrid1_LoadingRow" 
       CurrentCellChanged="dataGrid1_CurrentCellChanged" SelectionChanged="dataGrid1_SelectionChanged"
       SelectedCellsChanged="dataGrid1_SelectedCellsChanged" >
      <DataGrid.RowHeaderTemplate>
      <DataTemplate>
       <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRow}}, Path=Header}"></TextBlock>
      </DataTemplate>
      </DataGrid.RowHeaderTemplate>
       </DataGrid>

    As I explained earlier,

    We entered text in the horizontal cells(A1,B1,C1,D1.....)

    Selected all the cells in which data is entered and clicked on delete button in the keyboard. all values are deleted.Then,selected the first cell(A1) and entered some text and clicked on tab key continuously. Then,Deleted data are showing in the cells upon pressing  tab key in the respective cells.

    For Delete and Tab keys we are handling

    Grid_KeyUp event.Code snippet for this event is as following.

    private void Grid_KeyUp(object sender, KeyEventArgs e)
     {
      try
      {
      if (e.Key.ToString().Equals("Tab"))
      {
       if (dataGrid1.CurrentCell.Column != null)
       {
       if ((dataGrid1.CurrentCell.Column.DisplayIndex == (dataGrid1.Columns.Count - 1)))
       {
    
        DataTable dt = GetDataSet();//creates the datatable with the current data grid's data.
        DataColumn dc = new DataColumn();
        dt.Columns.Add(dc);
        dataGrid1.DataContext = dt;
        dataGrid1.Focus();
        
       }
       }
      }
      
      else if (e.Key == Key.Delete)
      {
       IList<DataGridCellInfo> cellList = dataGrid1.SelectedCells;
       if (cellList != null)
       {
       for (int i = 0; i < dataGrid1.SelectedCells.Count; i++)
       {
        DataGridCellInfo _cellInfo = cellList[i];
    
        if ((_cellInfo.Column.GetCellContent(_cellInfo.Item)) != null)
        {
        if ((_cellInfo.Column.GetCellContent(_cellInfo.Item)).GetType().Name.Equals("TextBlock"))
        {
       
    txtBlock = (_cellInfo.Column.GetCellContent(_cellInfo.Item)) as TextBlock;
         txtBlock.Text = string.Empty;//Here, We are clearing Data grid cell value
         
        }
        }
       }
       
       }
    
      }
      }
      catch (Exception ex)
      {
    through ex;  
      }
    
    In this way,we are implementing. If you get any solution for this,please provide me.
    
    Wednesday, October 20, 2010 5:14 AM
  • Hi Naga Bushan,

    Thank you for your valuable feedback!

    Based on the code snippets you supplied, I have noticed that you are using below logic to clear the content of DataGridCell.

    txtBlock = (_cellInfo.Column.GetCellContent(_cellInfo.Item)) as TextBlock;
    txtBlock.Text = string.Empty;
    

    DataGrid uses DataGridTextColumn to represent a column that hosts textual content in its cells by default. There are two different ways to represent DataGridCell content: TextBlock for read-only cell and Textbox for editable cell.

     In your case, you are clearing cell content by TextBlock. However the underlying data remains the same, so does the TextBox Control. When tab key pressed the specified cell get focused and turn into editable state. The DataGridCell now represents the underlying data through TextBox as you could see.

    Based on my understanding, I suggest you to delete the underlying data when you want to clear the DataGridCell content.

    Hope it helps! If you still have any questions or doubts please feel free to let me know.

     

    Best regards,

    Yves


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
    Wednesday, October 20, 2010 7:14 AM
    Moderator
  • Hi Yves,

    Thanks for your quick response.

    In our datagrid,to represent the Datagridcell content we are using textblock in editable mode.

    We are using following code snippet for that.

    <DataGrid.RowHeaderTemplate>
     <DataTemplate>
      <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRow}}, Path=Header}"></TextBlock>
     </DataTemplate>
     </DataGrid.RowHeaderTemplate>
     
    

     Do you know any way to delete the underlying data permanently, when I want to clear the DataGridCell content.(which is represented by textblock)

    Please provide  a solution which is applicable to textblock as we are using it to represent the datagrid cell content.

    Wednesday, October 20, 2010 10:12 AM
  • Hi Naga bushan,

    What i mean is that you should change the binding ItemsSource data of your DataGrid. Are you expecting that clearing all contents of cells in one row and a empty content row left?  If that is the case, you should modify your underlying data and then you could clear the TextBlock like what you have done in earlier post.

    I write some code snippets for your reference as below,

    XMAL:

    <Window x:Class="data_grid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
      <Grid>
        <DataGrid AutoGenerateColumns="False" Name="dataGrid" CanUserAddRows="False" KeyUp="dataGrid_KeyUp" CanUserDeleteRows="False"
             ItemsSource="{Binding Rows}">
          
          <DataGrid.RowHeaderTemplate>
            <DataTemplate>
              <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRow}}, Path=DataContext.RowHeader}"></TextBlock>
            </DataTemplate>
          </DataGrid.RowHeaderTemplate>
        </DataGrid>
      </Grid>
    </Window>
    

    Code behind

      public partial class MainWindow : Window
      {
        public ObservableCollection<MyRowObject> Rows { get; set; }
        public MainWindow()
        {
          InitializeComponent();
          #region Data
          Rows = new ObservableCollection<MyRowObject>()
          {
            new MyRowObject()
            {
              RowHeader="Row Header 1",
              Cells = new ObservableCollection<Cell>()
              {
                new Cell(){Value = "1"},
                new Cell(){Value = "2"},
                new Cell(){Value = "3"}
              }
            },
            new MyRowObject()
            {
              RowHeader="Row Header 2",
              Cells = new ObservableCollection<Cell>()
              {
                new Cell(){Value = "1"},
                new Cell(){Value = "2"},
                new Cell(){Value = "3"}
              }
            },
            new MyRowObject()
            {
              RowHeader="Row Header 3",
              Cells = new ObservableCollection<Cell>()
              {
                new Cell(){Value = "1"},
                new Cell(){Value = "2"},
                new Cell(){Value = "3"}
              }
            }
          };
          #endregion
    
          this.DataContext = this;
    
          GenerateColumns(Rows, dataGrid.Columns);
        }
    
        private void GenerateColumns(ObservableCollection<MyRowObject> rows, ObservableCollection<DataGridColumn> columns)
        {
          if (rows != null && Rows.Count > 0)
          {
            int columnCount = Rows.ElementAt(0).Cells.Count;
            for (int i = 0; i < columnCount; i++)
            {
              Style cellStyle = new System.Windows.Style(typeof(DataGridCell));
              
              DataGridColumn column = new DataGridTextColumn()
              {
                Binding = new Binding(string.Format("Cells[{0}].Value", i)),
                Header = string.Format("Column {0}", i),
                CellStyle = cellStyle
              };
              columns.Add(column);
            }
          }
        }
    
        private void dataGrid_KeyUp(object sender, KeyEventArgs e)
        {
          if (e.Key == Key.Delete)
          {
            int index = dataGrid.SelectedIndex;
    
            int columnCount = Rows.ElementAt(0).Cells.Count;
    
            for (int i = 0; i < columnCount; i++)
            {
              Rows[index].Cells[i].Value = "";
            }
          }
        }
      }
      public class MyRowObject
      {
        public ObservableCollection<Cell> Cells { get; set; }
        public string RowHeader { get; set; }
      }
    
      public class Cell
      {
        public string Value { get; set; }
      }
    

    I use an ObservableCollection<MyRowObject> type Rows to be my binding ItemsSource. In KeyUp event, I found the index of selected row and clear the content of cells in the same row.

    If I misunderstand you could you please elaborate your exact needs?

     

    Best regards,

    Yves


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
    Friday, October 22, 2010 9:20 AM
    Moderator
  • Hi Yves,

    As you are thinking, iam not expecting that clearing all contents of cells in one row and a empty content row left.My requirement is deleting the content of a datagrid cell permanently,when delete key pressed.In my case it is clearing tempororily,but when I press Tab key continuously,deleted values  are replaced in respective cells.

    Code snippet  for event Grid_KeyUp, I alread posted earlier.If u need,u can refer once again.

    I need  a solution for deleting the content of a datagrid cell permanently.

    Please let me know, if you need any clarrification

    Thanks,

    Naga bushan

    Monday, October 25, 2010 7:18 AM
  • Hi Naga bushan,

    If you are not expecting one empty row left and delete the data permanently. In that case, does the built-in delete row feature work? What I mean is set CanUserDeleteRows property to true. So when you press delete key, the corresponding row will be deleted both in view and underlying data. For more information about CanUserDeleteRows property please refer to http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.canuserdeleterows.aspx

    Please feel free to let me know if I misunderstand you. Please elaborate your needs and let's figure out this issue!J

     

    Best regards,

    Yves


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
    Monday, October 25, 2010 8:35 AM
    Moderator
  • Hi Yves,

    I configured CanUserDeleteRows property of datagrid as true.After changing,when I run my application and open the Excel template very first time it is working fine.After that facing the same problem as earlier.

    Please let me know, if you need any clarrification

    Thanks,

    Naga bushan

    Monday, October 25, 2010 2:01 PM
  • Hi Naga bushan,

    Thank you for feedback!

    Since the CanUserDeleteRows property works for the first time I think I understand you right. Now I am curious about your excel template. Are you making it your ItemsSource data? What do you mean by saying 'after that' it doesn't work, reload it or something else? Please kindly elaborate your problem, It would be appreciated if you could supply a demo to show it, you could sent it to my microsoft mailbox v-yvesz at microsoft dot com. I will check it asap.

     

    Best regards,

    Yves


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
    Thursday, October 28, 2010 3:04 AM
    Moderator