creating a custom cell based on hidden grid data

7 posts, 2 answers
  1. Roman
    Roman avatar
    19 posts
    Member since:
    Apr 2019

    Posted 03 Feb Link to this post

    Hi there,

    I'm currently working on an application which needs an ImageColumn with two small checkboxes (without any text). The CheckState of the checkboxes is based on cell values. The clue is, that these cell values are hidden.
    I've seen in your documentation and in a few other threads, that the override method SetContentCore is to set the content based on the row data. Unfortunately, I couldn't find anything to get the data from hidden cells in the current row.

    1.protected override void SetContentCore(object value)
    2.{
    3.    this.RowElement.VisualCells ... // this contains only the visible cells
    4.}

    I'm wondering if it's possible to get the hidden cell values as well or if I could pass any data? One way I thought was to show the hidden cells, create my custom cell and then hide the cells again. But I think this is pretty ugly and I'm not even sure if it would work properly.

    Is there any solution for this?

    Kind Regards,
    Roman
  2. Roman
    Roman avatar
    19 posts
    Member since:
    Apr 2019

    Posted 03 Feb in reply to Roman Link to this post

    I forgot to add an image how the result should look like. See the attached image here.
  3. Answer
    Nadya
    Admin
    Nadya avatar
    341 posts

    Posted 06 Feb Link to this post

    Hello Roman,

    RadGridView uses UI virtualization which means that cell elements are created only for currently visible cells and are being reused during operations like scrolling, filtering, grouping and so on. This is why not all data row objects can be visible at the same time in the RadGridView estate area in your application. I suppose that you create a custom cell in order to show two checkboxes with an image. You are on the right to override the SetContentCore method that is used to update the checkboxes according to the cell value. Note, that you should access the data row which is represented as RowInfo and DataBoundItem that gets the data-bound object which populates the row.

    I created a sample example for your reference where I create a custom column with a custom cell and override the SetContentCore method. I use the ToggleStateChanged event to update the underlying data source accordingly as well. Please refer to the following code snippet:

     public RadForm1()
            {
                InitializeComponent();
    
                BindingList<RowItem> myList = new BindingList<RowItem>();
                myList.Add(new RowItem(new MyItem(true, true)));
                myList.Add(new RowItem(new MyItem(true, true)));
                myList.Add(new RowItem(new MyItem(true, true)));
                myList.Add(new RowItem(new MyItem(false, false)));
                myList.Add(new RowItem(new MyItem(false, true)));
                myList.Add(new RowItem(new MyItem(false, true)));
                myList.Add(new RowItem(new MyItem(false, true)));
                
                CustomColumn customColumn = new CustomColumn("CustomColumn");
                customColumn.FieldName = "Item";
                this.radGridView1.Columns.Add(customColumn);
                this.radGridView1.DataSource = myList;
                this.radGridView1.TableElement.RowHeight = 60;
                
            }
        }
    
        public class CustomColumn : GridViewDataColumn
        {
            public CustomColumn(string fieldName)
                : base(fieldName)
            {
            }
    
            public override Type GetCellType(GridViewRowInfo row)
            {
                if (row is GridViewDataRowInfo)
                {
                    return typeof(CustomCellElement);
                }
                return base.GetCellType(row);
            }
        }
    
        public class CustomCellElement : GridDataCellElement
        {
            StackLayoutElement stack = new StackLayoutElement();
            private RadCheckBoxElement checkBox1;
            private RadCheckBoxElement checkBox2;
            public CustomCellElement(GridViewColumn column, GridRowElement row)
                : base(column, row)
            {
            }
    
            protected override void CreateChildElements()
            {
                base.CreateChildElements();
                stack.Orientation = Orientation.Vertical;
                this.checkBox1 = new RadCheckBoxElement();
                this.checkBox2 = new RadCheckBoxElement();
    
                stack.Children.Add(this.checkBox1);
                stack.Children.Add(this.checkBox2);
                this.Children.Add(stack);
                 
               this.checkBox1.ToggleStateChanged += this.CheckBox1_ToggleStateChanged;            
                this.checkBox2.ToggleStateChanged += this.CheckBox2_ToggleStateChanged;
           
            }
    
            private void CheckBox2_ToggleStateChanged(object sender, StateChangedEventArgs args)
            {
                MyItem item = this.RowInfo.Cells["Item"].Value as MyItem;
                item.isEnabled = checkBox2.IsChecked;
            }
    
            private void CheckBox1_ToggleStateChanged(object sender, StateChangedEventArgs args)
            {
                MyItem item = this.RowInfo.Cells["Item"].Value as MyItem;
                item.isActive = checkBox1.IsChecked;
            }
    
            protected override void SetContentCore(object value)
            {
                stack.Image = Properties.Resources.crayon;
                stack.StretchHorizontally = true;
                stack.StretchVertically = true;
    
                if (this.RowInfo != null && this.RowInfo.DataBoundItem != null && this.Value!=null)
                {
                    MyItem item = this.RowInfo.Cells["Item"].Value as MyItem;
                    this.checkBox1.ToggleStateChanged -= this.CheckBox1_ToggleStateChanged;
                    this.checkBox2.ToggleStateChanged -= this.CheckBox2_ToggleStateChanged;
    
                    this.checkBox1.IsChecked = item.isActive;
                    this.checkBox2.IsChecked = item.isEnabled;
                    this.checkBox1.ToggleStateChanged += this.CheckBox1_ToggleStateChanged;
                    this.checkBox2.ToggleStateChanged += this.CheckBox2_ToggleStateChanged;
                }
            }
    
            protected override Type ThemeEffectiveType
            {
                get
                {
                    return typeof(GridDataCellElement);
                }
            }
    
            public override bool IsCompatible(GridViewColumn data, object context)
            {
                return data is CustomColumn && context is GridDataRowElement;
            }
        }
    
        public class RowItem
        {
            public MyItem Item { get; set; }
            public RowItem(MyItem myItem)
            {
                this.Item = myItem;
            }
        }
        public class MyItem
        {
            public MyItem(bool isActive, bool isEnabled)
            {
                this.isActive = isActive;
                this.isEnabled = isEnabled;
            }
    
           public bool isActive { get; set; }
    
           public bool isEnabled { get; set; }
        }

    I hope this information is useful. Let me know if you need further assistance.

    Regards,
    Nadya
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  4. Roman
    Roman avatar
    19 posts
    Member since:
    Apr 2019

    Posted 11 Feb in reply to Nadya Link to this post

    Hi Nadya,

    DataBoundItem is the answer :) This provides all my data and helps me achieving the result I want. Thanks for your help.

    Best Regards,
    Roman
  5. Roman
    Roman avatar
    19 posts
    Member since:
    Apr 2019

    Posted 12 Feb Link to this post

    Hi Nadya,

    I think I'm gonna write this here because it affects this topic. My grid looks good and almost everything is working fine. My problem now is, that I need a few tooltips. I need a tooltip for each checkbox and for the column itself (for the image).

    I see that there is a ToolTipText property. I used it like this:

    radCheckBoxElement1.ToolTipText = "Tooltip for Checkbox 1";
    radCheckBoxElement2.ToolTipText = "Tooltip for Checkbox 2";
    this.ToolTipText = "Tooltip for the cell";

     

    But my problem is, that the checkbox selection area is the full width of the cell. So wherever I hover the cell, it either activates the upper or the lower checkbox. See the attachments, the images explain it better than I ever could ;-P
    As you can see on the images, I clearly didn't hover the checkbox. Yet it displays the tooltip for the checkboxes instead of the tooltip of my cell.

    Is there any solution for this?

    Best Regards,
    Roman

  6. Answer
    Nadya
    Admin
    Nadya avatar
    341 posts

    Posted 14 Feb Link to this post

    Hello Roman,

    You can change the size of the RadCheckBoxElements in order to show tooltip for the custom cell element as well as tooltips for the checkboxes:

    this.checkBox1.MaxSize = new Size(30, 0);
    this.checkBox2.MaxSize = new Size(30, 0);

    I hope this helps. Should you have other questions do not hesitate to ask.

    Regards,
    Nadya
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  7. Roman
    Roman avatar
    19 posts
    Member since:
    Apr 2019

    Posted 14 Feb Link to this post

    Hi Nadya,

    Great. This works good. Thank you very much :)
    Have a nice weekend.

    Best Regards,
    Roman

Back to Top