Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
1180
CheckBoxUIElement in group headers acts strange when used to hide columns
posted

In my previous post I have asked for excel-like functionlity for column grouping and hiding (not possible). Below there is a solution which almost works, problems are described at the bottom. NA2010 vol 3 was used.

Step 1: Create and assign creation filter

MyGridFilter filter = new MyGridFilter();

private void Form1_Load(object sender, EventArgs e)
{
            m_gridVariant.CreationFilter = filter;
}

Step 2 : filter implementation

 public class MyGridFilter : IUIElementCreationFilter
    {
        public void AfterCreateChildElements(UIElement parent)
        {
            HeaderUIElement header = parent as HeaderUIElement;
            if (header != null && header.Header.Column == null) //this will ensure its a group header
            {
                //region remove old instances (if present)
                foreach (UIElement e in header.ChildElements)
                {
                    if (e is MyCheckboxUIElement)
                        header.ChildElements.Remove(e);
                }
               
                //create new element
                MyCheckboxUIElement ele = new MyCheckboxUIElement(header);
               
                //gather group columns so that you know what to hide
                foreach (UltraGridColumn col in header.Header.Group.Columns)
                    ele.AddColumn(col);

                //add to child elements
                header.ChildElements.Add(ele);
            }
        }

        public bool BeforeCreateChildElements(UIElement parent){ return false; }
    }

Step 3 : Implement my checkbox so that it could do the hiding job

 public class MyCheckboxUIElement : CheckBoxUIElement
    {
        public MyCheckboxUIElement(UIElement parent) : base(parent)
        {
            //set checkbox rectangle
            int x, y, w, h;
            w = 20;
            h = parent.RectInsideBorders.Height - 2;
            x = parent.RectInsideBorders.Right - 22;
            y = parent.RectInsideBorders.Y + 2;
            this.Rect = new Rectangle(x, y, w, h);

            //base.ButtonStyle = UIElementButtonStyle.WindowsVistaButton; //how?
            base.CheckState = System.Windows.Forms.CheckState.Unchecked;
            base.ThreeState = false;
            base.ButtonType = UIElementButtonType.Toggle; //have no effect on appearance
        }
        protected override void OnCheckStateChange()
        {
            base.OnCheckStateChange();

            if (base.CheckState == System.Windows.Forms.CheckState.Checked)
                foreach (UltraGridColumn col in myColumns)
                    col.Hidden = true;
            else
                foreach (UltraGridColumn col in myColumns)
                    col.Hidden = false;
        }

}

Problems/Questions:

#1 When using base.IsChecked instead of base.CheckState it always returns false value. Checkbox acts properly - one mouse click makes it "checked", why IsChecked doe not work?

#2 Implementation above works, but following things are happening:

a.) when user clicks checkbox for the first time columns become hidden, but checkbox is turned back to unchecked state after it was handled. OnCheckStateChange is not triggered

b.) When columns are still hidden, checkbox is still unchecked, user clicks on it it changes from unchecked to checked (code has no effect, columns are already hidden)

c.) unchecking the checkbox causes column to appear just fine.

What and why is happenning in 2a, that causes checkbox to uncheck on it's own after columns are hidden. Are there any events I could handle?

 

Parents
No Data
Reply
  • 469350
    Offline posted

    Hi,

    I'm not sure why IsChecked it not working. But it's not a good idea to rely on the checked state of the UIElement, anyway.

    A UIElement is a transitory object, so you should never use it to store information that needs to persist. In this case, you should really be setting the CheckState of your derived CheckBoxUIElement based on the current state of the columns in the group rather than the other way around.

    So, in the constructor for your derived element, you have this line of code:

    base.CheckState = System.Windows.Forms.CheckState.Unchecked;

    This makes the assumption that the checkbox is unchecked and that all of the columns are currently visible. You appear to be assuming that the CreationFilter only fires the first time the grid is displayed and then you are relying on the check state to determine whether to make the columns visible or not. But this is a bad assumption. The CreationFilter will get called many many time for all sorts of reasons. And it is almost certainly getting called at some point after the columns have been hidden and then you are setting it's CheckState back to Unchecked.

    Anyway... what you should be doing, instead, is to set the CheckState based on the current visibility of the columns. So check the first column in the collection (if there is one) and use it's Hidden property to determine whether the UIElement's CheckState should be checked or unchecked.

Children