I have a grid with multiple columns but only two columns cells can be edited the rest of the columns cannot be. The two columns are both check editors. They can select any of the cells in the column but I want to limit them to only selecting cells in a single column at time. For instance, if the two columns are Active and Inactive the user should be able to select cells in Active or Inactive just not at the same time. I was also wondering if there is a way to only allow certain summaries. For instance, a string in my case doesn't need to have average etc. but we would like for the end user to be able to select count which in some cases is very useful.
Hello Michael,
I have been investigating into your requirement to limit the UltraGrid selection to cells from one column at a time, and I would recommend taking a look at the attached sample project.
There is no dedicated property for this, but you can utilize the BeforeSelectChange event of the grid to check the cells that are coming in versus the ones that are already selected and check the Column of each for differences. This event is cancellable, and when cancelled, the cells that were going to be selected will not be.
Please let me know if you have any other questions or concerns on this matter.
UltraGridSelectFromOneColumn.zip
I was hoping for a property but I could not find one. I thought about doing something similar to attached project sample. I will implement this and see how it goes. Thanks.
Should I make a separate post for the summary question?
My apologies, I must have missed the summary question in your original post.
At the moment, there is unfortunately no property on the columns to directly control which summaries are available in the summary dialog that shows up. There are a couple of potential alternatives in this case though.
The first alternative I can recommend is to set the UltraGridLayout.Override.AllowRowSummaries property to AllowRowSummaries.BasedOnDataType. For string columns, though, this will actually disable the summaries.
The other alternatives in this case involve handling the BeforeSummaryDialog event of the UltraGrid. The event arguments of this event will net you the summary dialog that is opening, and you can either dig into the Controls collection of this dialog and remove elements from it or cancel the event and show your own dialog to act as the summary selection dialog. The following code snippet demonstrates how you can remove a checkbox from the summary dialog in the BeforeSummaryDialog event:
private void UltraGrid1_BeforeSummaryDialog(object sender, BeforeSummaryDialogEventArgs e) { var panel = e.SummaryDialog.Controls[0].Controls[0].Controls[1]; List<CheckBox> checkboxesToRemove = new List<CheckBox>(); foreach(var x in panel.Controls) { string type = x.GetType().Name; if(x is CheckBox) { var checkbox = x as CheckBox; if(checkbox.Text == "Average") { checkboxesToRemove.Add(checkbox); } } } foreach(CheckBox check in checkboxesToRemove) { panel.Controls.Remove(check); } }
Please let me know if you have any other questions or concerns.
This should work great. Thanks.
A couple things about this approach.
First, the dialog typically disables the checkboxes, it doesn't remove them. So removing them might have unintended consequences if the dialog assumes that the controls are still there or gets re-used. Also, I would rely on the Text, since that can be changed via localization. Lastly, using indexes for controls (like this code does in order to get the panel) may not always be reliable, since the structure of the dialog might change. It would be better overall and more stable to use the names of those controls.
Here's an alternative solution that I think will be a littler more solid and reliable and less subject to breakage.
List<Control> checkboxesToDisable; private void UltraGrid1_BeforeSummaryDialog(object sender, BeforeSummaryDialogEventArgs e) { if (e.Column.DataType == typeof(string)) { Control sumCheckBox = e.SummaryDialog.Controls.Find("sumCheckBox", true)[0]; Control averageCheckBox = e.SummaryDialog.Controls.Find("averageCheckBox", true)[0]; Control maximumCheckBox = e.SummaryDialog.Controls.Find("maximumCheckBox", true)[0]; Control minimumCheckBox = e.SummaryDialog.Controls.Find("minimumCheckBox", true)[0]; Control countCheckBox = e.SummaryDialog.Controls.Find("countCheckBox", true)[0]; // Decide which checkboxes to include here. this.checkboxesToDisable = new List<Control>() { sumCheckBox, averageCheckBox, maximumCheckBox, minimumCheckBox, countCheckBox }; e.SummaryDialog.Shown += this.SummaryDialog_Shown; } } private void SummaryDialog_Shown(object sender, EventArgs e) { ((Form)sender).Shown -= this.SummaryDialog_Shown; foreach (Control control in checkboxesToDisable) { control.Enabled = false; } }
I noticed yesterday while trying different options that for columns with data types of Boolean or String that Average and Sum were disabled. The code example from yesterday pointed me in the direction I need to mimic that. The controls did get disabled but once the summary form was shown the controls were no longer disabled. I assumed the shown or load event for the form was overriding the properties. The code you provided will fix the issue with shown overriding my property changes. Plus the added reliability of using the control names instead of the text because the names of the controls are less likely to change. I tested the code in my current project and works as expected. Thanks. I am a little surprised that setting summaries to be BasedOnDataType removes the summary button for strings and boolean's. I would have thought Count would be available for all data types because it is not data related. I am sure there is a reason for it. Thanks for your time.
Yeah, BasedOnDataType essentially differentiates between numeric columns and Date columns, since summaries like Sum don't make sense for dates. I, too, was surprised to discover the BasedOnDataType completely removes the summary icon for Strings. I don't know for sure why it was done that way. But if I had to guess, I imagine the thinking goes something along the lines of - if you want a Count of the rows in the grid, you can get it from ANY column so having only a single option for string columns isn't very useful.