<
telerikGrid:GridViewCheckBoxColumn
DataMemberBinding
=
"{Binding Path=ActiveFlag}"
IsVisible
=
"False"
AutoSelectOnEdit
=
"True"
IsThreeState
=
"False"
>
<
telerikGrid:GridViewCheckBoxColumn.Header
>
<
CheckBox
Content
=
"Active"
Click
=
"HeaderCheckBox_Click"
IsThreeState
=
"False"
/>
</
telerikGrid:GridViewCheckBoxColumn.Header
>
</
telerikGrid:GridViewCheckBoxColumn
>
private
void
HeaderCheckBox_Click(
object
sender, RoutedEventArgs e)
{
CheckBox cb = (CheckBox)sender;
GridViewHeaderCell header = cb.ParentOfType<GridViewHeaderCell>();
ReferenceGrid.BeginEdit();
foreach
(GridViewRowItem item
in
ReferenceGrid.ChildrenOfType<GridViewRowItem>())
{
foreach
(var cell
in
item.Cells)
{
if
(cell.Column == header.Column)
{
if
(cell
is
GridViewCell)
{
GridViewCell c = (GridViewCell)cell;
c.BeginEdit();
CheckBox checkbox = c.GetEditingElement()
as
CheckBox;
if
(checkbox !=
null
)
checkbox.IsChecked = cb.IsChecked;
c.CommitEdit();
}
break
;
}
}
}
ReferenceGrid.CommitEdit();
}
17 Answers, 1 is accepted
RadGridView enables virtualization by default and as a result when working directly with the UI elements (in your case when checking/unchecking CheckBoxes), this may result in unexpected for the end-user behavior. Meaning that some of the checked CheckBoxes may become unchecked and vise versus. That is why the recommended way is to use data items, for example you may expose a new property responsible for the state of those Check Boxes.
Another possible approach, depending on your requirements, may be to use RadGridView's GridVewSelectColumn.
If none of those is helpful for your application, please share more details about your requirements and project's settings, so that I can provide with a more suitable solution or a sample project if needed.
Maya
the Telerik team
If you want the CheckBox in the Column's Header just to mark all the items in the grid as "Purchased" for example, you may loop through all the items and set their property "IsPurchased" to "true".
For example:
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
CheckBox headerCheckBox = e.OriginalSource as CheckBox;
if(headerCheckBox.IsChecked == true)
{
foreach(Player item in this.playersGrid.Items)
{
item.IsActive = true;
}
}
}
Another possibility may be to create your custom column implementing the functionality you want as described in this blog post.
Sincerely yours,
Maya
the Telerik team
BTW, I am on build 2010.2.812.1040.
public
override
FrameworkElement CreateCellElement(Telerik.Windows.Controls.GridView.GridViewCell cell,
object
dataItem)
{
var cb = cell.Content
as
CheckBox;
if
(cb ==
null
)
{
cb =
new
CheckBox();
cb.IsThreeState =
false
;
cb.SetBinding(CheckBox.IsCheckedProperty,
this
.DataMemberBinding);
cell.Content = cb;
}
return
cb;
}
public
override
FrameworkElement CreateCellEditElement(Telerik.Windows.Controls.GridView.GridViewCell cell,
object
dataItem)
{
var cb = cell.Content
as
CheckBox;
if
(cb ==
null
)
{
cb =
new
CheckBox();
cb.IsThreeState =
false
;
cb.SetBinding(PmcCheckBox.IsCheckedProperty,
this
.DataMemberBinding);
cell.Content = cb;
}
return
cb;
}
I am senidng you a sample project illustrating how to create a custom CheckBoxColumn. It simulates the behavior of a GridViewSelectColumn with the difference that it is bound to a specific property but not to IsSelected property of the GridViewRow. You may use it as a reference and change it so that it reponds to your requirements.
In case you have any further questions or difficulties, do not hesitate to get back to us.
Maya
the Telerik team
Unfortunately, I still ran into some minor issues with the project you sent. I noticed that the XAML in the project didn't reference the new custom column, and once I changed that the example project basically had the same issues I had been seeing in my app. When the page first loads the checkboxes have the correct state, and you can toggle all of them using the header checkbox. However, once you change the state of one of the checkboxes in the grid, it seems to lose the binding or something and the header checkbox will no longer affect the state of the one that you have clicked. Does that make sense?
I tried augmenting the custom column code you sent by adding an implementation for CreateCellEditElement that was practically identical to the CreateCellElement implementation. When I did this there were odd COM exceptions being thrown when I clicked on a checkbox in any one row. The only thing I could get to work to my satisfaction was using a DataTemplate (see below). I'm not sure how this was different than just implementing those 2 methods, but it seems to work.
I also added an AutoRowEditBehavior that would cause the checkbox to be toggled automatically when the cell is clicked in order to get around that issue of having to click multiple times in order to toggle a checkbox in a grid row.
protected
override
void
OnDataMemberBindingChanged()
{
base
.OnDataMemberBindingChanged();
if
(
this
.DataMemberBinding ==
null
)
return
;
// Use a data template, because overriding the 2 create element functions like normal seems to cause odd problems when trying to make the checkbox editable with a single click
StringBuilder sb =
new
StringBuilder();
sb.Append(
"<DataTemplate "
);
sb.Append(
"xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' "
);
sb.Append(
"xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' >"
);
sb.AppendFormat(
"<CheckBox IsChecked='{{Binding Path={0}, Mode=TwoWay}}' HorizontalAlignment='Center' IsThreeState='False' />"
,
this
.DataMemberBinding.Path.Path);
sb.Append(
"</DataTemplate>"
);
var dt = (DataTemplate)XamlReader.Load(sb.ToString());
this
.CellTemplate = dt;
this
.CellEditTemplate = dt;
}
The problem that is happening is if I override those 2 methods, I get a value outside of expected range exception when I expand the row details and then click the checkbox in the row. The exception seems to occur when BeginEdit is called as part of the AutoRowEditBehavior. Note that this does NOT happen if I use a DataTemplate as outlined above.
Firstly, please excuse me for the late response.
I am sending you the sample project with some changes made so that it is a bit clearer and more applicable. Mainly, what needs to be done is to set the Mode of the Binding for that custom column to "TwoWay".
Please let me know if it helps. In case it does not, I would need more information about your application and its settings. It would be great if it is possible to send me a sample project with your exact requitements via support ticket.
Maya
the Telerik team
Also, when I try using your method the binding doesn't seem to cause the underlying data to change in my app even though it seems to in yours. I think it has to do with the edit mode or selection mode (I am using cell selection), because I can't find any other real differences between your example and mine other than the fact that I am using the 8/12 build. I do notice in both my grid and yours that when you click in the cell but outside the checkbox itself, it seems to put the cell in edit mode and the checkbox gets smaller as if it is a different rendered control.
The upshot is that I have this mostly working, but I had to use the template method and an Auto-edit behavior to put the cell in edit mode during the MouseLeftButtonDown event.
I don't suppose there is a way to just put the cell perpetually in edit mode when using a checkbox?
I have tested my sample project and the underlaying data is updated as expected, no matter of the edit mode or the selection unit. As for the skipping the visual state of edit mode of that custom column, you may set its property IsReadOnly to "True". I am sending you the updated sample project that introduces that setting and defines a RowDetailsTemplate.
Maya
the Telerik team
Any help would be appreciated. Thanks.
May you shed some more light on the exact problems you encountered so that we could concentrate on them right away ? Is there any particular part of the code that you cannot convert ?
Maya
the Telerik team
Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>
Anyway, here is my scenario... I have a RadGridView with row details, I have a field "isChecked" as boolean that binds in a checkbox, this field will determine who is the checked items then it will mark the data to 'true' when selected. Now, I am able to do that scenario... The thing is, I also added checkbox for the header template... The main problem is that the checkbox header is not firing an event. I would like to fire an event because I want to collect all those items that is marked "isChecked = True"
Kindly help me with this matter... Thanks.
I tried your code and got the "{System.StackOverflowException}" exception at the setter of the "Header" property in the "CustomCheckBoxColumn.cs" file. Do you have any idea?
By the way, I included this customized checkbox column in the "telerik:GridViewColumnCollection" tag in the "UserControl.Resources" of the xaml file as following:
<
UserControl.Resources
>
<
telerik:GridViewColumnCollection
x:Name
=
"CustomColumnDefinition"
>
<
my:CustomCheckBoxColumn
DataMemberBinding
=
"{Binding IsChecked, Mode=TwoWay}"
IsReadOnly
=
"True"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Path=otherproperty1}"
Header
=
"Resource Name"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Path=otherproperty2}"
Header
=
"Resource Description"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Path=otherproperty3}"
Header
=
"IPType"
/>
</
telerik:GridViewColumnCollection
>
</
UserControl.Resources
>
Thanks for any suggestions.
Some suggestions:
- In you sample code, I'd like to see the functions of :
a. If all the checkboxes in the column are checked, the checkbox in the header cell should be checked as well
b. If any of the checkboxes in the column is/are unchecked, the checkbox in the header cell should be unckecked if it is checked.
2. In the "SelectOrDeselectAllItems" method in the "CustomCheckBoxColumn.cs" file, if you change the "Player" type in the foreach loolp to "var", this class can be used for any types.
SelectOrDeselectAllItems
You can subscribe to the Checked event of the CheckBox in CreateCellElement method and verify whether all items in the Items collection have the corresponding property set to "true". Once you confirm that all of them are 'True', you can set IsChecked of the Header CheckBox to "true". The same approach could be used in the reverse case - in the Checked event handler, if a single item's property is set to 'false', set header's CheckBox to 'false'.
Considering the second requirement, I am not quite sure what is the question here. Did you not managed to implement the code for different than 'Player' type ?
Maya
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
Thanks for the reply.
Did you have any suggestions about the "{System.StackOverflowException}" exception?
This is my top priority concern.
Thanks.
The thing is that I could not get the exception you mentioned. Is there anything more specific that you do in order to get it ? Why do you need such column collection defined in the Resources section ?
Maya
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>