views:

1828

answers:

5

Hello WPF experts:

I have the next code where I defined a WPF toolkit datagrid control called dgQuery; I filled this one with information of a dataset, then I inserted a new checkbox column in dgQuery to check/uncheck some of the rows, I show part of my C# code:

dgQuery.DataContext = dS.Tables[0];

DataGridTemplateColumn cbCol = new DataGridTemplateColumn();
cbCol.Header = "Opc";
FrameworkElementFactory factory = new FrameworkElementFactory(typeof(CheckBox));
Binding bind = new Binding("IsSelected");
bind.Mode = BindingMode.TwoWay;
factory.SetValue(CheckBox.IsCheckedProperty, bind);
DataTemplate cellTemplate = new DataTemplate();
cellTemplate.VisualTree = factory;
cbCol.CellTemplate = cellTemplate;
dgQuery.Columns.Insert(0, cbCol);

After checking/unchecking into the new checkbox column of the dgQuery rows I will click a button to save into a database only the rows I checked. The question is, how can I develop the loop for reading all the rows of dgQuery and the condition that will let me know which rows have the checkbox checked/unchecked? Help me with an example, please.

Thanks!!

+2  A: 

this will return a 'row' in your datagrid

public IEnumerable<Microsoft.Windows.Controls.DataGridRow> GetDataGridRows(Microsoft.Windows.Controls.DataGrid grid)
    {
        var itemsSource = grid.ItemsSource as IEnumerable;
        if (null == itemsSource) yield return null;
        foreach (var item in itemsSource)
        {
            var row = grid.ItemContainerGenerator.ContainerFromItem(item) as Microsoft.Windows.Controls.DataGridRow;
            if (null != row) yield return row;
        }
    }

in wpf datagrid, rows are ItemSource.items... no Rows property!

Hope this helps...

Tony
Tnxs Tony! Let me ask you how can I evaluate if the check box column I inserted is checked/unchecked and in general, how Can I retrieve all the cells of every DataGridRow?
Tristan
A: 
 var row = GetDataGridRows(dataGrid1);
 /// go through each row in the datagrid
            foreach (Microsoft.Windows.Controls.DataGridRow r in row)
            {
                DataRowView rv = (DataRowView)r.Item;

                // Get the state of what's in column 1 of the current row (in my case a string)
                string t = rv.Row[1].ToString();


            }
Tony
Tony, thank you again. One more question please, how can I evaluate the content of the column "opc" where the checkBox is defined? In the DataRowView I can only see the dataset columns, not the checkbox. Regards.
Tristan
Why don't you try MarkB's solution for your accessing your checkbox's in your datagrid?
Tony
I've asked the question again for you on this forum, because I couldn't find how to do it myself, so here's the thread with an answer: http://stackoverflow.com/questions/1936732/datagridtemplatecolumn-get-value-of-cellUse the answer I've accepted! I haven't tried it myself, but it look s like it should work! Good luck! Let me know what happened on it please?
Tony
Tony, again thanks for your help. I read 1936732 and I had many doubts in applying to my case so, I decided to use your original solution, First, I added a new column of type Bool to the dataset so it now simulates a checkbox (although I check double-clicking :-)), I think it is and easy and clean solution by the moment. My best regards.
Tristan
+1  A: 

Not sure if this is helpful because it assumes a different approach than what you started with, but rather than working directly with the grid, you could bind it to an ObservableCollection of objects that have properties for each column. If you add a bool property in your object for "Selected" and bind the checkbox column to it, you can then query the collection at any time for what is currently selected, like this:

 List<MemberEntity> selectedItems = 
            new List<MemberEntity>(from memberEntity in _memberEntities 
                                   where memberEntity.Selected == true 
                                   select memberEntity);

        //now save selectedItems to the database...

So MemberEntity is a class that has a property for each of the columns in your grid, including a bool called Selected for the checkbox column. _memberEntities is an ObservableCollection of MemberEntity instances. The grid's ItemSource property is bound to _memberEntities and each of its column's Binding properties are bound to a property in MemberEntity like this, assuming that Selected and Name are properties in MemberEntity:

<tk:DataGrid ItemsSource="{Binding _memberEntities}">
        <tk:DataGrid.Columns>
            <tk:DataGridCheckBoxColumn Binding="{Binding Path=Selected}" />
            <tk:DataGridTextColumn Binding="{Binding Path=Name}" />
        </tk:DataGrid.Columns>
</tk:DataGrid>
MarkB
Mark, thank you for your time and help. I need to read about ObservableCollection object before applying to my situation.
Tristan
Sounds good Tristan. The main advantage to using this approach is the separation of your code from the presentation. So your code focuses on a collection instead of a UI control. That means that if you change the UI control later, your code will probably not have to change. Also, unit testing is easier because you can programatically set up the select items by manipulating the collection instead of trying to manipulate the UI.
MarkB
A: 

Is tk.DataGrid a System.Windows.Controls.DataGrid ? In my code, i have a similar requirement,but there is'nt any ItemContainerGenerator property for the Datagrid. Do i need to include any directive or namespace to get that property... basically i need to loop through the grid to access the TextBox in TemplateColumn. Any help would be a


            <data:DataGridTemplateColumn Header="Quantity">
                <data:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
       <TextBox x:Name="txtQty" TextAlignment="Right" Tag="{Binding Price}" ></TextBox>
                    </DataTemplate>
                </data:DataGridTemplateColumn.CellTemplate>
            </data:DataGridTemplateColumn>

            <data:DataGridTemplateColumn Header="Amount">
                <data:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                  <TextBlock x:Name="txtAmount" TextAlignment="Right"></TextBlock>
                    </DataTemplate>
                </data:DataGridTemplateColumn.CellTemplate>
            </data:DataGridTemplateColumn>

        </data:DataGrid.Columns>
    </data:DataGrid>
Ankita Jain
A: 

//Looping thought datagrid rows & loop though cells and alert cell values

var row = GetDataGridRows(DataGrid_Standard); /// go through each row in the datagrid foreach (Microsoft.Windows.Controls.DataGridRow r in row) { DataRowView rv = (DataRowView)r.Item; foreach (DataGridColumn column in DataGrid_Standard.Columns) {

                    if (column.GetCellContent(r) is TextBlock)
                    {
                        TextBlock cellContent = column.GetCellContent(r) as TextBlock;
                        MessageBox.Show(cellContent.Text);
                    }
                    else if (column.GetCellContent(r) is CheckBox)
                    {
                        CheckBox chk = column.GetCellContent(r) as CheckBox;
                        MessageBox .Show (chk.IsChecked.ToString());
                    }                      

                }
            } 

public IEnumerable GetDataGridRows(Microsoft.Windows.Controls.DataGrid grid) {

        var itemsSource = grid.ItemsSource as IEnumerable;

        if (null == itemsSource) yield return null;

        foreach (var item in itemsSource)
        {

            var row = grid.ItemContainerGenerator.ContainerFromItem(item) as Microsoft.Windows.Controls.DataGridRow;

            if (null != row) yield return row;

        }

    }
Gayathri Gollavilli