none
Datagrid CheckBox Column

    Question

  • Hi community,

    i need to check all the checkboxes in the datagrid using LINQ instead of FOR or FOREACH  can it possible. 

    Monday, October 18, 2010 5:49 AM

Answers

  • Hi NavinKumar
    I create test application with 50000 rows and it works for me  very fast with simple foreach and two way binding.

    <sdk:DataGrid x:Name="dgData" ItemsSource="{Binding Persons}">
                <sdk:DataGrid.Columns>
                    <sdk:DataGridTemplateColumn Header="Some header">
                        <sdk:DataGridTemplateColumn.HeaderStyle>
                            <Style TargetType="Primitives:DataGridColumnHeader">
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate>
                                            <Grid>
                                                <CheckBox x:Name="cbxHeader" Checked="cbxHeader_CheckedChanged" Unchecked="cbxHeader_CheckedChanged"/>
                                            </Grid>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </sdk:DataGridTemplateColumn.HeaderStyle>
                        <sdk:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox  VerticalAlignment="Center" IsChecked="{Binding HavePet, Mode=TwoWay}" HorizontalAlignment="Center" />
                            </DataTemplate>
                        </sdk:DataGridTemplateColumn.CellTemplate>
                    </sdk:DataGridTemplateColumn>
                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
    public partial class CheckboxColumn : UserControl
        {
            CheckboxColumnViewModel dc = new CheckboxColumnViewModel();
    
            public CheckboxColumn()
            {
                InitializeComponent();
                
                Random rnd = new Random(DateTime.Now.Second);
                for (int i = 0; i < 50000; i++)
                {
                    dc.Persons.Add(new Person() { Age = rnd.Next(80) + 10, Name = "Mister " + i.ToString(), HavePet = true });
                }
                dgData.DataContext = dc;
            }
    
            private void cbxHeader_CheckedChanged(object sender, RoutedEventArgs e)
            {
                foreach (Person p in dc.Persons)
                    p.HavePet = (sender as CheckBox).IsChecked.HasValue && (sender as CheckBox).IsChecked.Value;
            }
        }
    
        public class CheckboxColumnViewModel
        {
            private readonly ObservableCollection<Person> _persons = new ObservableCollection<Person>();
    
            public ObservableCollection<Person> Persons
            {
                get { return _persons; }
            }
    
        }
    public class Person
    {
    .....
    
            private bool _havePet;
            public bool HavePet
            {
                get { return _havePet; }
                set
                {
                    _havePet = value;
                    NotifyPropertyChanged("HavePet");
                }
            }
    
    ......
    }


    Check this sample code


    Wednesday, October 20, 2010 2:28 AM
  • I suppose you classes are partial, so you can just add boolean property to those classes in separate code file without changing existing files. Just add something like "bool IsChecked { get; set; }" to you class at client side, since you not need this value at serverside do not make this property serializable, and you can use it in bindings.

    Friday, October 22, 2010 2:12 AM

All replies

  • Hi,

    If you use List you can use ForEach() method,

    Else convert to list by using ToList() then use ForEach(),

    Or make custom extension method.

    Monday, October 18, 2010 7:14 AM
  • if you want to bind data using LINQ then List() is the best collection for returning result.

    directly assing List() result control with ItemSource Property,

    also make AutoGenerateColumns="True"

    Monday, October 18, 2010 7:35 AM
  • Hi,

    i dont want to use for or foreach in my collection. because i have some thousands of records so its not possible to loop all over my records and also i have 30 to 40 columns so its hard to loop all the items so i like to go with some other way.

    Monday, October 18, 2010 8:35 AM
  • Hi,

    and one more thing all over this. I like to filter the rows which was checked in my datagrid. 

    more over can we use dinding path to check all the check box some thing like this.

    <sdk:DataGridTemplateColumn Width="SizeToHeader">
    <sdk:DataGridTemplateColumn.HeaderStyle>
    .....
    <CheckBox  Margin="5,0,0,0" Content="Select All" x:Name="HeaderChk" VerticalAlignment="Center" Click="CheckBox_Click" HorizontalAlignment="Center"></CheckBox>
    .....
    </sdk:DataGridTemplateColumn.HeaderStyle>
    <sdk:DataGridTemplateColumn.CellTemplate>
                        			<DataTemplate>
                                        <CheckBox  VerticalAlignment="Center" IsChecked="{Binding HeaderChk}" Click="CheckboxClick" Tag="{Binding NO, Mode=TwoWay}" HorizontalAlignment="Center" />
                        			</DataTemplate>
                        		</sdk:DataGridTemplateColumn.CellTemplate>
    </sdk:DataGridTemplateColumn>

    Is it possible to do like this

    Monday, October 18, 2010 8:44 AM
  • LINQ will do the same operation - iterate through you collection using foreach. In case of correct LINQ you will get same performance or if you have not good LINQ expression you will get even worse performance comparing with standard foreach loop. It is not true only in case when you use LINQ to Entities or LINQ to SQL where you have Queriable collections.

    Sorry, but it looks that you do not know this :)

    So conclusion - feel free to use standard foreach or for.

    Monday, October 18, 2010 8:45 AM
  • Ok Andris,

    is there is some other way for this because my application getting slow because of foreach and for can you suggest some other way to do this.

    Monday, October 18, 2010 8:48 AM
  • Directly bind list collection with itemsouce simple

    Monday, October 18, 2010 8:51 AM
  • what is your source ? and what are you returnig from linq query ??

    List collection ? or what ?

    Monday, October 18, 2010 8:53 AM
  • Hi,

    Add Computed Properties on the Silverlight Client. Or you can override Datacontext and bind chectbox to that object if you DB does not have True or False.

    using System.ServiceModel.DomainServices.Client;
    
    namespace RIAServicesExample.Web
    {
      public partial class Object : Entity
      { 
        public bool CheckTrue 
        { 
          get { return True; } 
        } 
        partial void OnCheckChanged() 
        { 
          this.RaisePropertyChanged("PropertyName"); 
        } 
      }
    }
     
    Best regrads
    Thaicarrot
    Monday, October 18, 2010 9:06 AM
  • If you have all you thousands of rows visible, application will be definetly slow. I suppose you have some paging - so first option you can change only visible rows. Knowing page size and page number it should be easy.

    If you have collection in memory with some class, and this class have bool property "HeaderChk" you can use your binding, and than iterating through whole collection and changing this boolean must be very fast even with thousands of rows. But again, if you have large visible page binding will work slow,  if you have normal page (less than 100 rows) all must be fast.

    Another option - you can bind one checkbox to another like:

    IsChecked="{Binding Path=IsChecked, ElementName=HeaderChk}"
    I'm not sure that binding to elements works in styles, but you can try.

    Monday, October 18, 2010 9:06 AM
  • hi andris,

    This thing does not works i tried it with a new application  

    Tuesday, October 19, 2010 1:35 AM
  • Hi NavinKumar
    I create test application with 50000 rows and it works for me  very fast with simple foreach and two way binding.

    <sdk:DataGrid x:Name="dgData" ItemsSource="{Binding Persons}">
                <sdk:DataGrid.Columns>
                    <sdk:DataGridTemplateColumn Header="Some header">
                        <sdk:DataGridTemplateColumn.HeaderStyle>
                            <Style TargetType="Primitives:DataGridColumnHeader">
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate>
                                            <Grid>
                                                <CheckBox x:Name="cbxHeader" Checked="cbxHeader_CheckedChanged" Unchecked="cbxHeader_CheckedChanged"/>
                                            </Grid>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </sdk:DataGridTemplateColumn.HeaderStyle>
                        <sdk:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox  VerticalAlignment="Center" IsChecked="{Binding HavePet, Mode=TwoWay}" HorizontalAlignment="Center" />
                            </DataTemplate>
                        </sdk:DataGridTemplateColumn.CellTemplate>
                    </sdk:DataGridTemplateColumn>
                </sdk:DataGrid.Columns>
            </sdk:DataGrid>
    public partial class CheckboxColumn : UserControl
        {
            CheckboxColumnViewModel dc = new CheckboxColumnViewModel();
    
            public CheckboxColumn()
            {
                InitializeComponent();
                
                Random rnd = new Random(DateTime.Now.Second);
                for (int i = 0; i < 50000; i++)
                {
                    dc.Persons.Add(new Person() { Age = rnd.Next(80) + 10, Name = "Mister " + i.ToString(), HavePet = true });
                }
                dgData.DataContext = dc;
            }
    
            private void cbxHeader_CheckedChanged(object sender, RoutedEventArgs e)
            {
                foreach (Person p in dc.Persons)
                    p.HavePet = (sender as CheckBox).IsChecked.HasValue && (sender as CheckBox).IsChecked.Value;
            }
        }
    
        public class CheckboxColumnViewModel
        {
            private readonly ObservableCollection<Person> _persons = new ObservableCollection<Person>();
    
            public ObservableCollection<Person> Persons
            {
                get { return _persons; }
            }
    
        }
    public class Person
    {
    .....
    
            private bool _havePet;
            public bool HavePet
            {
                get { return _havePet; }
                set
                {
                    _havePet = value;
                    NotifyPropertyChanged("HavePet");
                }
            }
    
    ......
    }


    Check this sample code


    Wednesday, October 20, 2010 2:28 AM
  • hi andris,

    Sorry for my late reply and thankyou very much for yours reply. But this reply doesn't answers my question because what you have done is you have created a class with bool field(Byte filed sql server) but i dont have such bool field in my database table.

    So i am using a template field like you have done in datagrid in selection changed event i am getting the selected items and type casting to my actual table so i can get the data from the selected item but except the (bool filed)template column because that column does not belongs to my class type so here come the trouble.

    and more over i can alter my table(in database and .edmx) because i  have created  some custom class(es) in domainservice it is not possible for me to change all the work what have i done. Is there is any other solution for this please tell me some other reply

    Friday, October 22, 2010 1:19 AM
  • I suppose you classes are partial, so you can just add boolean property to those classes in separate code file without changing existing files. Just add something like "bool IsChecked { get; set; }" to you class at client side, since you not need this value at serverside do not make this property serializable, and you can use it in bindings.

    Friday, October 22, 2010 2:12 AM
  • Dear Navin,


    Please follow the below link:

    http://www.hookedonlinq.com/UpdateOperator.ashx


    they use .Update method for updating List/Collection


    Regards,

    Zeeshan Raees.

    Please Mark answer if helpful

    Friday, October 22, 2010 2:42 AM
  • hi Andris,

    Ok ill try in this way thanks you once again for you support and reply..

    Friday, October 22, 2010 5:53 AM
  • Hi Zeeshan Raees,

    Finally i got a solution for my problem thaks for reply.

    Friday, October 22, 2010 6:26 AM