GridViewDataColumn with CheckBox as CellTemplate does not change selection when check-box is ticked (WPF MVVM)

14 posts, 0 answers
  1. Itai
    Itai avatar
    6 posts
    Member since:
    Mar 2014

    Posted 11 Aug 2014 Link to this post

    I created a GridViewDataColumn in my MVVM WPF project with CheckBox as its CellTemplate, properly bound to a boolean property of the DataContext. When I tick the check-box for the currently-selected row, everything works fine. But when I do it for a different row, the current selection does not move to that row (as it would when clicking on a text field, for instance) even though the view-model item for that row gets updated about the check-box state change.
    I tried several solutions with no help, such as:
    http://www.telerik.com/forums/problem-with-gridviewcheckboxcolumn-in-wpf
    http://www.telerik.com/forums/propagating-gridviewcheckboxcolumn-selection-to-datamemberbinding-in-edit-mode
    http://www.telerik.com/forums/gridviewcomboboxcolumn-update-on-change

    Can you think of any reason this would happen?
  2. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 11 Aug 2014 Link to this post

    Hi,

    I attached a demo solution to illustrate how to make a bound select column.
    There are three options defined:
    - with bound GridViewCheckBoxColumn,
    - with bound GridViewDataColumn defining a CellTemplate
    - with GridViewColumn defining a CellTemplate.

    Regards,
    Didie
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  3. UI for WPF is Visual Studio 2017 Ready
  4. Itai
    Itai avatar
    6 posts
    Member since:
    Mar 2014

    Posted 11 Aug 2014 Link to this post

    Hi, Didie.

    Thanks for your quick response, but unfortunately I have seen this solution a few times. It provides several ways to implement SelectColumn, which is not what I need.
    A SelectColumn cell is checked if-and-only-if its row is selected. Clicking anywhere in any row in your solution either adds that row to the selection (thereby checking the SelectColumn cells in that row) or removes it from the selection (thereby unchecking the SelectColumn cells in that row).
    What I need is a simple check-box that contains boolean data that is irrelevant to whether or not the row is selected, much like the content of a text cell does not change when selecting or deselecting its row.
    A good example for such a column in your football club project would be a "Played at World Cup" column where contents of check-boxes do not change according to row selection.
    I tried GridViewCheckBoxColumn but it only updates the underlying item on LostFocus, not on Click as I want. I tried GridViewDataColumn and it does update on Click, but does not change the currently selected row when I click in the check-box of another row.
    Can you help please?
  5. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 12 Aug 2014 Link to this post

    Hello,

    You can check the Number of clicks in the CheckBox column article on how to control the number of clicks needed to edit the bound value.

    For example:
    <telerik:GridViewCheckBoxColumn
           Header="CheckBoxColumn"
           EditTriggers="CellClick"
           AutoSelectOnEdit="True"
           DataMemberBinding="{Binding IsChampion}" />

    I hope this helps.

    Regards,
    Didie
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  6. Itai
    Itai avatar
    6 posts
    Member since:
    Mar 2014

    Posted 12 Aug 2014 in reply to Dimitrina Link to this post

    Hello, Didie.

    I have already tried this solution and, as mentioned in my previous reply, it only updates the underlying item on LostFocus, not on Click as I want.
    I understand that updating on LostFocus is by-design, but I also have text columns and they have telerik:TextBoxBehavior.UpdateTextOnTextChanged="True" which does update the underlying item on text change, even before LostFocus. I am just looking for its parallel in check-box columns.
    Any other ideas?
  7. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 12 Aug 2014 Link to this post

    Hello,

    I am afraid I cannot suggest the same solution for GridViewCheckBoxColumns.
    Actually all the columns does not respect the UpdateSourceTrigger=PropertyChanged option. 

    You can define CellTemplate for the column to get the desired result:
    <telerik:GridViewColumn Header="Update on PropertyChanged" Width="60" IsReadOnly="True">
        <telerik:GridViewColumn.CellTemplate>
            <DataTemplate>
                <CheckBox HorizontalAlignment="Center" IsChecked="{Binding IsChampion, Mode=TwoWay}"/>
            </DataTemplate>
        </telerik:GridViewColumn.CellTemplate>
    </telerik:GridViewColumn>
     
    That way the value of the bound property will be updated once you click in the CheckBox. Is any reason why you cannot use this approach?

    Regards,
    Didie
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  8. Itai
    Itai avatar
    6 posts
    Member since:
    Mar 2014

    Posted 13 Aug 2014 in reply to Dimitrina Link to this post

    Hello, Didie.

    I already tried using CellTemplate (with DataTemplate containing CheckBox) and, as mentioned in a previous reply (regarding GridViewDataColumn but also true regarding GridViewColumn) it does update on Click, but does not change the currently selected row when I click in the check-box of another row. The requirement is to both move to the row of the clicked check-box AND update the underlying item on click.
    Note that I do not insist on using GridViewCheckBoxColumn - any check-box-looking solution is fine with me as long as it follows MVVM principles. (I am even willing to break that a little, using code-behind and such, as long as it gets the job done.)
    Given that, can you think of anything else, even not involving GridViewCheckBoxColumn?
  9. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 13 Aug 2014 Link to this post

    Hello,

    It actually works fine in the project I previously sent. I am attaching an updated version of it where the CheckBox is bound to a new boolean IsChampion property. 
    You can refer to the "With CellTemplate Champion" column.

    Additionally, you can try specifying UpdateSourceTrigger="PropertyChanged".
    For example:
    <telerik:GridViewColumn Header="Update on PropertyChanged" Width="60" IsReadOnly="True">
        <telerik:GridViewColumn.CellTemplate>
            <DataTemplate>
                <CheckBox HorizontalAlignment="Center" IsChecked="{Binding IsChampion, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
            </DataTemplate>
        </telerik:GridViewColumn.CellTemplate>
    </telerik:GridViewColumn>


    Regards,
    Didie
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  10. Itai
    Itai avatar
    6 posts
    Member since:
    Mar 2014

    Posted 18 Aug 2014 in reply to Dimitrina Link to this post

    Hello, Didie.

    Thanks for your example. It is closer to what I need (separating check-box content from current selection) but still problematic. You will see what I mean if you turn the grid's SelectionMode to Single. (This is what I use, but it is also problematic in Multiple mode.)
    Also, append the following two to the end of the column list to see the behavior I do need:

    <telerik:GridViewDataColumn Header="Name1" DataMemberBinding="{Binding Name, Mode=TwoWay}">
        <telerik:GridViewDataColumn.CellEditTemplate>
            <DataTemplate>
                <TextBox Text="{Binding Name, Mode=TwoWay}" telerik:TextBoxBehavior.UpdateTextOnTextChanged="True" />
            </DataTemplate>
        </telerik:GridViewDataColumn.CellEditTemplate>
    </telerik:GridViewDataColumn>
    <telerik:GridViewDataColumn Header="Name2" DataMemberBinding="{Binding Name, Mode=TwoWay}">
        <telerik:GridViewDataColumn.CellEditTemplate>
            <DataTemplate>
                <TextBox Text="{Binding Name, Mode=TwoWay}" telerik:TextBoxBehavior.UpdateTextOnTextChanged="True" />
            </DataTemplate>
        </telerik:GridViewDataColumn.CellEditTemplate>
    </telerik:GridViewDataColumn>

    The first thing you notice is that clicking anywhere on the grid (apart from the With CellTemplate Champion column) sets the currently-selected row to where you clicked. This is the behavior I need for the With CellTemplate Champion column, too.
    You might say that this is fulfilled by CheckBoxColumn that both changes the currently-selected row AND sets IsChampion independently to the currently-selected row. However, it updates the underlying object on LostFocus, not on Click. The With CellTemplate Champion column does update the underlying object on Click, but does not set the currently-selected row to where you clicked.
    The behavior I need from the check-box column is the one shown by the two text-box columns appended by the snippet above: they both update the currently-selected row to where you clicked, AND update the underlying object on each keyboard press.
    Again, I don't mind breaking MVVM principles a little (using code-behind and such) in order to get the right behavior.
  11. Yoan
    Admin
    Yoan avatar
    1070 posts

    Posted 19 Aug 2014 Link to this post

    Hi,

    Generally RadGridView supports selection out-of-the-box. However, in your case, you want to perform this action using a control placed in CellTemplate of the column(the CheckBox).  If you click on the cell which contains the control, you will actually click in the CheckBox instead of GridViewRow/GridViewCell, so RadGridView's selection logic will not work.

    What you can do is to use CheckBox's Checked/Unchecked event and add the corresponding item(you can get it through the DataContext of the Checkbox) in GridView's SelectedItems collection. You can check the following code snippet for a reference:
    <telerik:RadGridView.Columns>
                    <telerik:GridViewColumn Header="With CellTemplate Champion">
                        <telerik:GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"  IsChecked="{Binding IsChampion}"></CheckBox>
                            </DataTemplate>
                        </telerik:GridViewColumn.CellTemplate>
                    </telerik:GridViewColumn>             
                </telerik:RadGridView.Columns>
               .
               .
               .
     private void CheckBox_Checked(object sender, RoutedEventArgs e)
            {
                 
                var item = (sender as CheckBox).DataContext as Club;
     
                if (item!=null)
                {
                    this.clubsGrid.SelectedItems.Add(item);
                }
            }
     
            private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
            {
                 
                var item = (sender as CheckBox).DataContext as Club;
     
                if (item!=null)
                {
                    this.clubsGrid.SelectedItems.Remove(item);
                }
            }

    I hope this helps.

    Regards,
    Yoan
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  12. crazy05
    crazy05 avatar
    72 posts
    Member since:
    Sep 2014

    Posted 08 Jul 2015 in reply to Yoan Link to this post

    Yoan said:Hi,

    Generally RadGridView supports selection out-of-the-box. However, in your case, you want to perform this action using a control placed in CellTemplate of the column(the CheckBox).  If you click on the cell which contains the control, you will actually click in the CheckBox instead of GridViewRow/GridViewCell, so RadGridView's selection logic will not work.

    What you can do is to use CheckBox's Checked/Unchecked event and add the corresponding item(you can get it through the DataContext of the Checkbox) in GridView's SelectedItems collection. You can check the following code snippet for a reference:
    <telerik:RadGridView.Columns>
                    <telerik:GridViewColumn Header="With CellTemplate Champion">
                        <telerik:GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"  IsChecked="{Binding IsChampion}"></CheckBox>
                            </DataTemplate>
                        </telerik:GridViewColumn.CellTemplate>
                    </telerik:GridViewColumn>             
                </telerik:RadGridView.Columns>
               .
               .
               .
     private void CheckBox_Checked(object sender, RoutedEventArgs e)
            {
                 
                var item = (sender as CheckBox).DataContext as Club;
     
                if (item!=null)
                {
                    this.clubsGrid.SelectedItems.Add(item);
                }
            }
     
            private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
            {
                 
                var item = (sender as CheckBox).DataContext as Club;
     
                if (item!=null)
                {
                    this.clubsGrid.SelectedItems.Remove(item);
                }
            }

    I hope this helps.

    Regards,
    Yoan
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     

     I like your solution. 

    How can we implement this(Check/Uncheck) is MVVM ?

  13. Yoan
    Admin
    Yoan avatar
    1070 posts

    Posted 08 Jul 2015 Link to this post

    Hello Ram,

    You can try to create a custom column. You can check this or this help article for a reference. Please let me know if you need further assistance with this.

    Regards,
    Yoan
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  14. crazy05
    crazy05 avatar
    72 posts
    Member since:
    Sep 2014

    Posted 08 Jul 2015 in reply to Yoan Link to this post

    Yoan said:Hello Ram,

    You can try to create a custom column. You can check this or this help article for a reference. Please let me know if you need further assistance with this.

    Regards,
    Yoan
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items

    Hello Yoan,

     

    Thank you for quick reply. I want to change the color of the gridViewCell when user check the checkbox. I want to change only the color of the Checkbox GridviewCell. How can I do this in MVVM. I used the below code in non-MVVM 

    private void Grid_OnChecked(object sender, RoutedEventArgs e)
            {
                var parent = (sender as CheckBox).ParentOfType<GridViewCell>();
                parent.Background = Brushes.Yellow;           
            }

  15. Dimitrina
    Admin
    Dimitrina avatar
    3769 posts

    Posted 13 Jul 2015 Link to this post

    Hi,

    In order to apply conditional styling based on the bound property value changed, I would suggest you applying a CellStyleSelector. You can also check the CellStyleSelector online demo (or the same available with your local WPF Demos). 

    Regards,
    Dimitrina
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
UI for WPF is Visual Studio 2017 Ready