WCF/WF - How to get the wpf datagrid cell value

Asked By Ramesh Nalla
10-Nov-11 12:49 AM
Hi All,

Can any one please help me ..

i have a wpf datagrid having two coloumns Empname ,address based on the condtion i want to get the TextBlock Text  .


 

<DataGridTemplateColumn Header="Empname">

 

<DataGridTemplateColumn.CellTemplate>

 

<DataTemplate>

 

<Button Margin="5" Content="employees" Cursor="Hand" Name="BtnTest" Click="btnEmp_Click">

 

<Button.Template>

 

<ControlTemplate TargetType="Button">

 

<TextBlock TextDecorations="Underline" Text="{Binding Path=empname}" > <ContentPresenter />

 

</TextBlock>

 

</ControlTemplate>

 

</Button.Template>

 

<Button.Style>

 

<Style TargetType="Button">

 

<Setter Property="Foreground" Value="Blue" />

 

<Style.Triggers>

 

<Trigger Property="IsMouseOver" Value="true">

 

<Setter Property="Foreground" Value="Green" />

 

</Trigger>

 

</Style.Triggers>

 

</Style>

 

</Button.Style>

 

</Button>

 

</DataTemplate>

 

</DataGridTemplateColumn.CellTemplate>

 

</DataGridTemplateColumn>


how to get the Textblock text  in runtime .?


Regards
Ramesh
  James H replied to Ramesh Nalla
10-Nov-11 01:00 AM
check if code below would work for you:
private void dataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    DataGrid dataGrid = sender as DataGrid;
    if (e.AddedItems!=null && e.AddedItems.Count>0)
    {
        // find row for the first selected item
        DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromItem(e.AddedItems[0]);
        if (row != null)
        {
            DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);
            // find grid cell object for the cell with index 0
            DataGridCell cell = presenter.ItemContainerGenerator.ContainerFromIndex(0) as DataGridCell;
            if (cell != null)
            {
                Console.WriteLine(((TextBlock)cell.Content).Text);
            }
        }
    }
}

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;
}

hope this helps, regards

  Suchit shah replied to Ramesh Nalla
10-Nov-11 01:04 AM

DataGrid is one kind of ItemsControl, so it has the Items property and the ItemContainer that wraps the item. It is different with DataGridView in Windows Forms, the DataGridRow is an item in the Items collection and the cell is wrapped in a DataGridCellsPresenter structure; so we cannot get the cell content like DataGridView.Rows.Cells. However, In WPF we can access to the element in the control through VisualTree, of cause can access the DataGridRow and the DataGridCellsPresenter in the DataGrid via VisualTree; and get the cell instance in the DataGridCellsPresenter.
 DataGridRow rowContainer = (DataGridRow)dataGrid1.ItemContainerGenerator.ContainerFromIndex(rowIndex);
DataGridCellsPresenter presenter = GetVisualChild(rowContainer);
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex);

// ...

public 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(v);
    else
    break;
  }

  return child;
}



http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/d3d6b7ec-71f9-4011-afc5-0bf3956e6d78
  Suchit shah replied to Ramesh Nalla
10-Nov-11 01:04 AM

  you can read datagrid cell value without ObservableCollection values. You can read all cell data of your datagrid. i have sample for you in which the grid
 

       contain a comboBox in it's cell.
 
       the XAML for the dataGrid:
 
     

 <cmbGenerator:DataGridComboLoad x:Key="MajorProblemCombo"/>
 <DataGrid AutoGenerateColumns="False" Height="100" Foreground="Red" HorizontalAlignment="Left" Margin="2,1,0,0"<br/>     Name="majorAreaDataGrid" VerticalAlignment="Top" Width="158" AlternatingRowBackground="#FFCAEBE7" RowBackground="{x:Null}" >
    <DataGrid.Background>
     <ImageBrush />
   </DataGrid.Background>
     <DataGrid.Columns>
      <DataGridTemplateColumn Header="Main criteria" Width="150">
      <DataGridTemplateColumn.CellTemplate>
       <DataTemplate>
       <TextBlock Text="{Binding MajorProblem}"></TextBlock>
        </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
      <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
   <ComboBox Name="majorProblemComboBox" ItemsSource="{Binding Source={StaticResource MajorProblemCombo}}" <br/>   SelectedItem="{Binding MajorProblem,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource ComboBoxBGYellowGreen}"/>
        </DataTemplate>
      </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
        </DataGrid.Columns>
 </DataGrid>
 

and the C# code for your event:
 
 
 
 

   
   // Business logic class<br/>      FinalPrescriptionManager finalPrescriptionObj = new FinalPrescriptionManager();
      List<DoctorPrescription> listmajorCatagory = new List<DoctorPrescription>();
      int rowNo = 0;
      for (int row = 0; row < majorAreaDataGrid.Items.Count-1; row++)
      {
      try
      {
        DoctorPrescription docPresObj = new DoctorPrescription();
        docPresObj = (DoctorPrescription)(majorAreaDataGrid.Items[row]);
        rowNo++;
      }
      catch (Exception exception)
      {
        MessageBox.Show("Major problem dataGrid casting problem.", "Error-Casting", MessageBoxButton.OK, MessageBoxImage.Warning);
      }
      }
      if (majorAreaDataGrid.Items.Count > 1)
      {
      for (int count = 0; count < rowNo; count++)
      {
        DoctorPrescription doctorPresObj = new DoctorPrescription();
        try
        {
        doctorPresObj = (DoctorPrescription) (majorAreaDataGrid.Items[count]);
        listmajorCatagory.Add(doctorPresObj);
        }
        catch (Exception exception)
        {
        MessageBox.Show("Major problem DataGrid's cell data can't add in list.","Error-cell data adding in list",MessageBoxButton.OK,<br/>         MessageBoxImage.Warning);
        }
      }
   // Send the list in Business Logic Layer
      finalPrescriptionObj.SaveMagorCatagoryPrescription(listmajorCatagory);
      }
   
 

 

   Hope it will help you.

  Suchit shah replied to Ramesh Nalla
10-Nov-11 01:05 AM
There are no simple built-in methods for accessing individual rows or columns in WPF DataGrid. The following code samples will provide simple methods for accessing these items.

http://techiethings.blogspot.com/2010/05/get-wpf-datagrid-row-and-cell.html#!/2010/05/get-wpf-datagrid-row-and-cell.html
  Ramesh Nalla replied to James H
10-Nov-11 03:35 AM
Hi

i want to get the button content (TextBlock)text .. but your code gives Textblock text


Regards
Ramesh
  Ramesh Nalla replied to James H
10-Nov-11 03:40 AM
Hi

when iam using the same code getting this error

Unable to cast object of type 'System.Windows.Controls.ContentPresenter' to type 'System.Windows.Controls.TextBlock'.

Ramesh
  James H replied to Ramesh Nalla
10-Nov-11 03:45 AM
Cast according to the TextBlock.
Create New Account
help
i++) { Movie ei = (Movie)data[i]; ei.Index = i.ToString(); } } private void listview_SelectionChanged(object sender, SelectionChangedEventArgs e) { ItemContainerGenerator generator = this.listview.ItemContainerGenerator; ListViewItem selectedItem = (ListViewItem)generator.ContainerFromIndex(listview.SelectedIndex); TextBox tbFind foundElement = null; if (element is FrameworkElement) (element as FrameworkElement).ApplyTemplate(); for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) { Visual visual = VisualTreeHelper.GetChild(element, i) as Visual; foundElement = GetDescendantByType(visual, type, name); if (foundElement ! = null) break; } return i++) { Movie ei = (Movie)data[i]; ei.Index = i.ToString(); } } private void listview_SelectionChanged(object sender, SelectionChangedEventArgs e) { ItemContainerGenerator generator = this.listview.ItemContainerGenerator; ListViewItem selectedItem = (ListViewItem)generator.ContainerFromIndex(listview.SelectedIndex); TextBox tbFind foundElement = null; if (element is FrameworkElement) (element as FrameworkElement).ApplyTemplate(); for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) { Visual visual = VisualTreeHelper.GetChild(element, i) as Visual; foundElement = GetDescendantByType(visual, type, name); if (foundElement ! = null) break; } return
null; } After you get the DataGridCell, you might also need to get child visual by VisualTreeHelper class. Please refer to this post: http: / / blogs.msdn.com / vinsibal / archive / 2008 / 11 / 05 sample.aspx check if code below would work for you: private void dataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { DataGrid dataGrid = sender as DataGrid; if (e.AddedItems! = null && e.AddedItems.Count> 0) { / / find 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
null; } After you get the DataGridCell, you might also need to get child visual by VisualTreeHelper class. Please refer to this post: http: / / blogs.msdn.com / vinsibal / archive / 2008 / 11 / 05 x8x9zk5a.aspx check if code below would work for you: private void dataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { DataGrid dataGrid = sender as DataGrid; if (e.AddedItems! = null && e.AddedItems.Count> 0) { / / find 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
mehr. Danke f??r eure Hinweise Gruss Jakob - - Jakob Brunner Luzern, Switzerland C# - German Discussions VisualTreeHelper (1) GetChildrenCount (1) WPF (1) GetChild (1) Control (1) Visual (1) Jakob Brunner (1) Steuerelemente Jakob, Ggf. etwas wie: static public void EnumVisual(Visual myVisual) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(myVisual); i+ +) { Visual childVisual = (Visual)VisualTreeHelper.GetChild(myVisual, i); EnumVisual(childVisual); } } [VisualTreeHelper-Klasse (System.Windows.Media)] http: / / msdn.microsoft.com / de-de / library / system.windows.media.visualtreehelper.aspx ciao Frank - - Dipl.Inf. Frank Dzaebel [MCP / MVP C#] http: / / Dzaebel.NET keywords: Abfrage