none
CheckBox unchecks inside DataGridTemplateColumn

    Question

  • Hello, I have a CheckBox inside a DataGridTemplateColumn.  If I check some of the CheckBox's and then scroll them out of view using the DataGrid scroller they become unchecked.  I understand that using a DataGridCheckBoxColumn does not exhibit this behavior but I need to be able to handle the checked/unchecked events of the CheckBox and from what I understand these events are not available in the DataGridCheckBoxColumn.  Any help would be greatly appreciated.  I have included sample xaml and c# code behind.  Thank you. 

    <UserControl x:Class="CheckBoxTest.Page"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:cnt="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" 
        Width="400" Height="300">
        <Grid x:Name="LayoutRoot" Background="White" Height="200">
            <cnt:DataGrid x:Name="dgFiles"  AutoGenerateColumns="False" HeadersVisibility="Column" HorizontalAlignment="Stretch">
                <cnt:DataGrid.Columns>
                    <cnt:DataGridTemplateColumn Header="Test CheckBox" Width="40" IsReadOnly="True">
                        <cnt:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Grid>
                                    <CheckBox VerticalAlignment="Center" HorizontalAlignment="Center" IsThreeState="False" IsChecked="{Binding IsSelected, Mode=TwoWay}" />
                                </Grid>
                            </DataTemplate>
                        </cnt:DataGridTemplateColumn.CellTemplate>
                    </cnt:DataGridTemplateColumn>
                </cnt:DataGrid.Columns>
            </cnt:DataGrid>
        </Grid>
    </UserControl>
      
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace CheckBoxTest
    {
        public partial class Page : UserControl
        {
            public Page()
            {
                InitializeComponent();
                this.Loaded += new RoutedEventHandler(Page_Loaded);
            }
    
            private void Page_Loaded(object sender, RoutedEventArgs e)
            {
                List testList = new List();
    
                for (int i = 0; i < 25; i++)
                {
                    CheckBoxTestData td = new CheckBoxTestData();
                    testList.Add(td);
                }
    
                this.dgFiles.ItemsSource = testList;
            }
        }
    
        public class CheckBoxTestData
        {
            bool IsSelected { get; set; }
        }
    }
    
     
    Tuesday, January 27, 2009 4:33 PM

All replies

  •  The DataGridTemplateColumn should have a CellTemplate and CellEditingTemplate  when the cell is to be editable.  When the user clicks on a cell it will switch to using the Editing template. What you are doing is placing a editting control in the CellTemplate which is really only meant to display the data.  If you want the same behavior as the CheckBox column I would make the CheckBox in the cell template readonly (IsEnabled=False) and place an editable checkbox in the CellEditingTemplate

     

    http://msdn.microsoft.com/en-us/library/system.windows.controls.datagridtemplatecolumn(VS.95).aspx

    Thursday, January 29, 2009 2:51 PM
  • Thanks for the reply. I did try what you suggested but it still behaves the same as before.  Whenever I scroll the checkbox's out of view with the datagrid's scroll bar they become unchecked, they even fire their UnChecked events.  I thought it was simply a drawing problem but the fact that the UnChecked event is also raised makes it seem very strange.

    Thursday, January 29, 2009 3:26 PM
  • I am having the exact same problem with the Checkboxes checking/unchecking when I scroll my datagrid.  Any updates in the past 2 months? 

    Monday, March 30, 2009 10:41 AM
  • Following Code should work correctly with Silverlight 3:

     
    <data:DataGridTemplateColumn Header="CheckBoxColumn">
    
    <data:DataGridTemplateColumn.CellTemplate>
    
    <DataTemplate>
    
    <CheckBox IsChecked="{Binding Available}" IsEnabled="False"/>
    
    </DataTemplate>
    
    </data:DataGridTemplateColumn.CellTemplate>
    
    <data:DataGridTemplateColumn.CellEditingTemplate>
    
    <DataTemplate>
    
    <CheckBox IsChecked="{Binding Path=Available,Mode=TwoWay}"/>
    
    </DataTemplate>
    
    </data:DataGridTemplateColumn.CellEditingTemplate>
    
    </data:DataGridTemplateColumn>
    

     I can think of two possible conditions where you might be running into this:

    1. Cell Template and CellEditing Template both share the same template.
    2. The Binding is not set correctly to TwoWay.
    Gunjan Shah [MSFT]

     

    Monday, March 30, 2009 9:19 PM
  • I am also facing the same problem. While dragging using the scrollbar, already checked checkboxes are jumbled up and down. any solution??? im using silverlight2. pls help

    Friday, April 17, 2009 3:02 AM
  • This is not a bug.  What happens when you scroll around in the DataGrid is the same checkboxes are being used for new data because the DataGrid recycles the visuals.  When your new data has different values, the check will change through the Binding and you'll receive the event.  What you can do to get this scenario to work is to listen to LoadingRow which is raised when a row comes into view.  In there, you can call column.GetCellContents to get the contents of the cell.  This will give you the CheckBox, and you can attach to CheckChanged at this time.  If you do this, you need to do something similar and listen to UnloadingRow so you can detach the eventhandler when the checkbox is scrolled out of view.

    Friday, April 17, 2009 2:35 PM
  • Yifung, 

    I understand that Silverlight recycles visuals but if I scroll back to a check box shouldn't it go back to it's original state (checked or unchecked)? If this is not bug than it seems like a strange behavior to be by design.  If I understand your post you are telling me that I need to manage the state of checkboxes? This doesn't seem right.

    Tuesday, August 11, 2009 9:59 AM
  • Yes, it will go back to its original state if it's databound.  The behavior you're seeing where you check the checkboxes, scroll down, and scroll back up and the checkboxes are unchecked are because the DataBinding is OneWay instead of TwoWay.  As a result, when you checked the checkboxes, your item was not updated.  You can see this if you put a breakpoint in the setter of your entity.  If you make it a TwoWay binding, then the changes in the checkbox will be pushed back to your entity, and then when you scroll it back in, it'll be checked.

    Tuesday, August 11, 2009 1:29 PM
  • I have run into the same situation. It doesn't seem like a good design to force developers to manage the state of that checkbox ourselves. Why force us to keep track of wether we selected a particular record or not by adding a property to the object? All I want to do is list my records and be able to select some of them in order to perform some action on the selected ones. Managing that state is an extra hastle.

     I would still consider this a bug or a very poor design of the datagrid control. Microsoft, please reconsider this feature!!!

    Thanks!

    Thursday, August 13, 2009 11:34 AM
  • Thank you for your help, this solution worked.  However, I feel that the way Silverlight handles this situation is less than optimum for 2 reasons:

     1.  If you are just using the check box to signify that an item is selected you have to add a property to your entity to manage the state of the check box.

    2.  When Silverlight is recycling the visuals, it still fires the Checked, Unchecked events.  Obviously this causes a problem if you are subsribed to these events and are trying to execute code in the eventhandlers.  Unless there is a way to tell if the event is coming from Silverlight or an actual user clicking the checkbox.

    Thursday, August 13, 2009 1:28 PM
  • Yes, I do agree that there is a drawback to container recyling.  However, the performance difference between recycling vs not recyling is like light and day.  As a result, container recycling is a clear win for any data sets but the very small ones.

    Thursday, August 13, 2009 2:28 PM
  • Hi

     we are a new team of silverlight developers that has run into this problem.

    Could you please post a smal code example of how to attach/detach to the events on load/unloadRow. And what to do in these events. Note that we cant find the event CheckChanges on the CheckBox control.

     As mentioned earlier we just need to select a number of rows.

     

    Hope you can help

    Wednesday, August 26, 2009 4:43 AM
  • Do you have an example of this?  I cannot get it working.

    Wednesday, October 14, 2009 1:55 PM
  • Don't know this solution work for you or not, but it work for me.

     Since the grid automatically fire unchecked events of the checkboxes during unloading and loading rows, we just take out checked and unchecked event of the checkbox, replace it by Click event. When user fire Click event, change the IsChecked value to true or false.

     You may also need to attach loading and unloading row event to store the checkboxes state manually. that is, during loadingrow event, loop your stored checkboxe's states and assigning value back to checkbox, and during unloading row event, unchecked the row's checkbox.

     Hope this help :D

    Monday, November 02, 2009 8:41 AM
  • The same problem i am also having. please share the code for the sample for this issue. it would be greatful.

    Thanks and Regards

    Saji

    Friday, November 06, 2009 12:00 AM
  • I am using the following Design Code to bid checkbox in datagrid. I am still getting issues in scroll. If i use scroll bar down then those checked box become unchecked and unchecked box become checked ,its very strange issue , Could you suggest me how i can overcome the issue
    Tuesday, May 04, 2010 4:31 AM
  • I was also getting the same issue and I did some workaround for that.

    1. Edit the datagrid template.

    2. Put the RowsPresenter inside the ScrollViewer

             <ScrollViewer  HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"  VerticalScrollBarVisibility="Auto">
                   <dataPrimitives:DataGridRowsPresenter x:Name="RowsPresenter"/>
             </ScrollViewer>

    Hide the VerticalScrollBarVisibility for that datagrid because from now this scrollviewer will display the scrollbar.

    After that all the rows will load in a single shot inside the scrollviewer.

    Mark as answer if this will help you.

     

    Wednesday, June 30, 2010 5:40 AM
  • The first solution suggested by kianboo seems to be working for me. Need to bind the IsChecked property mode as Two way. Remove the check, unchecked event if subscribed, instead use the click event.
    Thursday, July 01, 2010 7:41 AM
  • I was also getting the same issue and I did some workaround for that.

    1. Edit the datagrid template.

    2. Put the RowsPresenter inside the ScrollViewer

             <ScrollViewer  HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"  VerticalScrollBarVisibility="Auto">
                   <dataPrimitives:DataGridRowsPresenter x:Name="RowsPresenter"/>
             </ScrollViewer>

    Hide the VerticalScrollBarVisibility for that datagrid because from now this scrollviewer will display the scrollbar.

    After that all the rows will load in a single shot inside the scrollviewer.

    Mark as answer if this will help you

    Tuesday, July 06, 2010 5:12 AM
  • The first solution suggested by kianboo seems to be working for me. Need to bind the IsChecked property mode as Two way. Remove the check, unchecked event if subscribed, instead use the click event.
    Tuesday, February 01, 2011 11:54 PM
  • Can you please elaborate this Available in your solution so that we can also try with this solution

    IsChecked="{Binding Available}"

    Thanks in advance

    Tuesday, February 15, 2011 7:32 AM
  • Can you please attach an example for the below solution

    <ScrollViewer  HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"  VerticalScrollBarVisibility="Auto">
                   <dataPrimitives:DataGridRowsPresenter x:Name="RowsPresenter"/>
             </ScrollViewer>

    Tuesday, February 15, 2011 7:34 AM

  • Monday, February 21, 2011 1:19 AM
  • Problem :

    <data:DataGrid x:Name="dtGrdCategory" HorizontalAlignment="Left" HeadersVisibility="None"
                           RowBackground="#1C1785E5" AlternatingRowBackground="Transparent" Background="Transparent"
                           Margin="171,230,0,44" RowHeight="29" HorizontalScrollBarVisibility="Disabled"
                           VerticalScrollBarVisibility="Auto" Width="556" AutoGenerateColumns="False"
                           GridLinesVisibility="None">
                <data:DataGrid.Columns>
                    <data:DataGridTemplateColumn Width="278">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox Tag="{Binding CategoryID}" Content="{Binding CategoryName}" Foreground="#ffffff"
                                          Margin="20,7,0,0"  Click="CheckBox_Checked"></CheckBox>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                    </data:DataGridTemplateColumn>
                    <data:DataGridTemplateColumn Width="278">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox Tag="{Binding CategoryID2}" Content="{Binding CategoryName2}"
                                          Visibility="{Binding visibility2}"  Foreground="#ffffff" Margin="20,7,0,0"  
                                          Click="CheckBox_Checked"></CheckBox>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                    </data:DataGridTemplateColumn>
                </data:DataGrid.Columns>
            </data:DataGrid>

     

    Solution :

    <ScrollViewer Width="556" Margin="0,225,0,44" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
                <data:DataGrid x:Name="dtGrdCategory" Height="Auto" HorizontalAlignment="Left" HeadersVisibility="None"
                               RowBackground="#1C1785E5" AlternatingRowBackground="Transparent" Background="Transparent"
                               RowHeight="29" Margin="-4,-4,0,0" HorizontalScrollBarVisibility="Disabled" BorderThickness="0"
                               Width="560" AutoGenerateColumns="False"
                               GridLinesVisibility="None" >

                    <data:DataGrid.Columns>
                    <data:DataGridTemplateColumn Width="278">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding Available}" Tag="{Binding CategoryID}" Content="{Binding CategoryName}" Foreground="#ffffff"
                                          Margin="20,7,0,0"  Click="CheckBox_Checked"></CheckBox>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                    </data:DataGridTemplateColumn>
                    <data:DataGridTemplateColumn Width="278">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding Available, Mode=TwoWay}" Tag="{Binding CategoryID2}" Content="{Binding CategoryName2}"
                                          Visibility="{Binding visibility2}"  Foreground="#ffffff" Margin="20,7,0,0"  
                                          Click="CheckBox_Checked"></CheckBox>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                    </data:DataGridTemplateColumn>
                </data:DataGrid.Columns>
            </data:DataGrid>

     

    If you have any problem in understanding above code write to me at gotoprashant@gmail.com Smile

    Monday, February 21, 2011 1:20 AM
  • Problem :

    <data:DataGrid x:Name="dtGrdCategory" HorizontalAlignment="Left" HeadersVisibility="None"
                           RowBackground="#1C1785E5" AlternatingRowBackground="Transparent" Background="Transparent"
                           Margin="171,230,0,44" RowHeight="29" HorizontalScrollBarVisibility="Disabled"
                           VerticalScrollBarVisibility="Auto" Width="556" AutoGenerateColumns="False"
                           GridLinesVisibility="None">
                <data:DataGrid.Columns>
                    <data:DataGridTemplateColumn Width="278">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox Tag="{Binding CategoryID}" Content="{Binding CategoryName}" Foreground="#ffffff"
                                          Margin="20,7,0,0"  Click="CheckBox_Checked"></CheckBox>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                    </data:DataGridTemplateColumn>
                    <data:DataGridTemplateColumn Width="278">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox Tag="{Binding CategoryID2}" Content="{Binding CategoryName2}"
                                          Visibility="{Binding visibility2}"  Foreground="#ffffff" Margin="20,7,0,0"  
                                          Click="CheckBox_Checked"></CheckBox>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                    </data:DataGridTemplateColumn>
                </data:DataGrid.Columns>
            </data:DataGrid>


    Solution :

    <ScrollViewer Width="556" Margin="0,225,0,44" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
                <data:DataGrid x:Name="dtGrdCategory" Height="Auto" HorizontalAlignment="Left" HeadersVisibility="None"
                               RowBackground="#1C1785E5" AlternatingRowBackground="Transparent" Background="Transparent"
                               RowHeight="29" Margin="-4,-4,0,0" HorizontalScrollBarVisibility="Disabled" BorderThickness="0"
                               Width="560" AutoGenerateColumns="False"
                               GridLinesVisibility="None" >

                    <data:DataGrid.Columns>
                    <data:DataGridTemplateColumn Width="278">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding Available}" Tag="{Binding CategoryID}" Content="{Binding CategoryName}" Foreground="#ffffff"
                                          Margin="20,7,0,0"  Click="CheckBox_Checked"></CheckBox>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                    </data:DataGridTemplateColumn>
                    <data:DataGridTemplateColumn Width="278">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding Available, Mode=TwoWay}" Tag="{Binding CategoryID2}" Content="{Binding CategoryName2}"
                                          Visibility="{Binding visibility2}"  Foreground="#ffffff" Margin="20,7,0,0"  
                                          Click="CheckBox_Checked"></CheckBox>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                    </data:DataGridTemplateColumn>
                </data:DataGrid.Columns>
            </data:DataGrid>


    If you have any problem in understanding above code write to me at gotoprashant@gmail.com Smile

    Monday, February 21, 2011 1:22 AM
  • The solution for this is -

    1. Add "Loaded" event for header checkbox. ie., Loaded="headerCheckBox_Loaded"

    2. Write below code in xaml.cs file -

    CheckBox objHeaderCheckBox = null;
    private void headerCheckBox_Loaded(object sender, RoutedEventArgs e)
    {
          objHeaderCheckBox = (CheckBox)sender;
    }


    3. Use where ever u want-

    objHeaderCheckBox.IsChecked = false; or objHeaderCheckBox.IsChecked = true;

    I have used this and ot's working fine for me. Mark as answer if it is corrent.

    Thnaks in advance

    Thursday, February 24, 2011 6:13 AM