GridView are wrong to display child controls

7 posts, 2 answers
  1. Paul
    Paul avatar
    34 posts
    Member since:
    Apr 2017

    Posted 02 May 2017 Link to this post

    Hi,

    I use GridView and custom cell element, however it is wrong to display, please help me to resolve it!

    My code and video demo below
    + Change page size -> scroll -> change form size to normal -> hide to task bar -> re-open from task bar -> wrong

    + video: https://youtu.be/8ytr-AFMzRc
    + my code:

    public partial class RadForm1 : Telerik.WinControls.UI.RadForm
        {
            public RadForm1()
            {
                InitializeComponent();
                this.ThemeName = "TelerikMetro";
                this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
     
                var layer1 = new TableLayoutPanel();
     
                layer1.Dock = DockStyle.Fill;
                layer1.Location = new Point(0);
                layer1.Margin = new Padding(0);
                layer1.ColumnCount = 2;
                layer1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 30F));
                layer1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
                layer1.RowCount = 2;
                layer1.RowStyles.Add(new RowStyle(SizeType.Absolute, 28F));
                layer1.RowStyles.Add(new RowStyle(SizeType.Absolute, 0F));
                layer1.AutoSize = true;
     
                var label = new RadLabel();
                label.Dock = DockStyle.Fill;
                label.Text = @"Test grid view";
                label.ThemeName = "TelerikMetro";
     
                layer1.Controls.Add(label, 0, 0);
                layer1.SetColumnSpan(label, 2);
     
                var radGridView1 = new RadGridView
                {
                    Dock = DockStyle.Fill,
                    AutoGenerateColumns = false,
                    AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill,
                    ThemeName = "TelerikMetroTouch",
                    AllowDeleteRow = false,
                    AllowAddNewRow = false,
                    // AllowEditRow = false,
                    EnableGrouping = false,
                    EnablePaging = true,
                    Margin = new Padding(5, 10, 5, 10),
                    PageSize = 10,
                    AllowColumnHeaderContextMenu = false,
                    AllowRowHeaderContextMenu = false
                };
     
                radGridView1.CreateCell += RadGridView1_CreateCell;
     
                radGridView1.Columns.Add(new GridViewMaskBoxColumn("col 1", "Column 1")
                {
                    HeaderText = @"",
                    ReadOnly = true,
                    Width = 280,
                    AllowSort = false,
                    AllowResize =  false,
                    AllowReorder = false
                });
     
                radGridView1.Columns.Add(new GridViewMaskBoxColumn("col 2", "Column 2"));
                radGridView1.Columns.Add(new GridViewMaskBoxColumn("col 3", "Column 3"));
                radGridView1.Columns.Add(new GridViewMaskBoxColumn("col 4", "Column 4"));
                radGridView1.Columns.Add(new GridViewMaskBoxColumn("col 5", "Column 5"));
                radGridView1.Columns.Add(new GridViewMaskBoxColumn("col 6", "Column 6"));
                radGridView1.Columns.Add(new GridViewMaskBoxColumn("col 7", "Column 7"));
                radGridView1.Columns.Add(new GridViewMaskBoxColumn("col 8", "Column 8"));
                radGridView1.Columns.Add(new GridViewMaskBoxColumn("col 9", "Column 9"));
                radGridView1.Columns.Add(new GridViewMaskBoxColumn("col 10", "Column 10"));
                radGridView1.Columns.Add(new GridViewMaskBoxColumn("col 11", "Column 11"));
     
                RenderData(radGridView1);
     
                GridViewUpdateHeight(radGridView1);
     
                var layer2 = new TableLayoutPanel();
     
                layer2.Dock = DockStyle.Fill;
                layer2.Location = new Point(0);
                layer2.Margin = new Padding(0);
                layer2.ColumnCount = 1;
                layer2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
                layer2.RowCount = 1;
                layer2.RowStyles.Add(new RowStyle(SizeType.Absolute, radGridView1.Height));
                layer2.AutoSize = true;
     
                layer2.Controls.Add(radGridView1, 0, 0);
     
                layer1.Controls.Add(layer2, 1, 1);
                layer1.RowStyles[1].SizeType = SizeType.AutoSize;
     
                Controls.Add(layer1);
            }
     
            private void GridViewUpdateHeight(RadGridView grid)
            {
                var actualRowCount = grid.RowCount < grid.PageSize ? grid.RowCount : grid.PageSize;
                var height = actualRowCount * 40;
     
                if (grid.AllowAddNewRow && !grid.ReadOnly)
                {
                    height += grid.MasterView.TableAddNewRow.GetActualHeight(grid.TableElement);
                }
                if (grid.EnableFiltering)
                {
                    height += grid.MasterView.TableFilteringRow.GetActualHeight(grid.TableElement);
                }
                if (grid.ShowColumnHeaders)
                {
                    height += grid.MasterView.TableHeaderRow.GetActualHeight(grid.TableElement);
                }
                if (grid.EnablePaging)
                {
                    height += 50;
                }
                height += 20; // horizontal scroll bar height
     
                grid.Height = height;
            }
     
            private void RenderData(RadGridView radGridView1)
            {
                for (int k = 0; k < 100; k++)
                {
                    GridViewDataRowInfo rowInfo = new GridViewDataRowInfo(radGridView1.MasterView);
                    rowInfo.Height = 40;
     
                    for (int i = 1; i < radGridView1.Columns.Count; i++)
                    {
                        rowInfo.Cells[i].Value = "Row: " + k + " - column: " + i;
                    }
     
                    radGridView1.Rows.Add(rowInfo);
                }
            }
     
            private void RadGridView1_CreateCell(object sender, GridViewCreateCellEventArgs e)
            {
                if (e.Row is GridFilterRowElement)
                    return;
     
                if (e.Column.Index == 0)
                {
                    if (e.Row is GridTableHeaderRowElement && e.CellType == typeof(GridHeaderCellElement))
                    {
                        e.CellElement = new PageSizeDropdownHeaderCellElement(e.Column, e.Row);
                    }
     
                    if (e.Row is GridDataRowElement)
                    {
                        var actionCellElement = new ActionCellElement(e.Column, e.Row);
                        e.CellElement = actionCellElement;
                    }
                }
            }
        }
     
        public sealed class PageSizeDropdownHeaderCellElement : GridHeaderCellElement
        {
            public PageSizeDropdownHeaderCellElement(GridViewColumn col, GridRowElement row) : base(col, row)
            {
                TextAlignment = ContentAlignment.TopCenter;
                Alignment = ContentAlignment.TopCenter;
                AutoSizeMode = RadAutoSizeMode.FitToAvailableSize;
            }
     
            private RadDropDownListElement _dropDownListElement;
     
            protected override void CreateChildElements()
            {
                base.CreateChildElements();
                if (_dropDownListElement?.DataSource == null)
                {
                    _dropDownListElement = new RadDropDownListElement();
                    _dropDownListElement.BindingContext = new BindingContext();
                    _dropDownListElement.DropDownStyle = Telerik.WinControls.RadDropDownStyle.DropDownList;
     
                    _dropDownListElement.Items.Clear();
                    _dropDownListElement.Items.Add(new RadListDataItem("10", 10) { Selected = true });
                    _dropDownListElement.Items.Add(new RadListDataItem("25", 25));
                    _dropDownListElement.Items.Add(new RadListDataItem("50", 50));
                    _dropDownListElement.Items.Add(new RadListDataItem("100", 100));
                    _dropDownListElement.Items.Add(new RadListDataItem("All", -1));
     
                    _dropDownListElement.Margin = new Padding(15, 0, 0, 0);
                    _dropDownListElement.StretchHorizontally = true;
                    _dropDownListElement.NotifyParentOnMouseInput = false;
                    _dropDownListElement.Popup.MouseClick -= Popup_MouseClick;
                    _dropDownListElement.Popup.MouseClick += Popup_MouseClick;
     
                    _dropDownListElement.PopupClosed -= _dropDownListElement_PopupClosed;
                    _dropDownListElement.PopupClosed += _dropDownListElement_PopupClosed;
     
                    _dropDownListElement.FitToSizeMode = RadFitToSizeMode.FitToParentPadding;
                    _dropDownListElement.AutoSizeMode = RadAutoSizeMode.FitToAvailableSize;
                    _dropDownListElement.AutoSize = true;
     
                    this.Children.Add(_dropDownListElement);
                }
            }
     
            private RadListVisualItem _elementUnderMouse;
     
            private void Popup_MouseClick(object sender, MouseEventArgs e)
            {
                _elementUnderMouse = _dropDownListElement.Popup.ElementTree.GetElementAtPoint(e.Location) as RadListVisualItem;
            }
     
            private void _dropDownListElement_PopupClosed(object sender, RadPopupClosedEventArgs args)
            {
                if (_elementUnderMouse == null)
                {
                    return;
                }
                if (_dropDownListElement.SelectedIndex == -1)
                    return;
     
                var pageSize = Convert.ToInt32(_elementUnderMouse.Data.Value);
     
                if (pageSize == -1)
                {
                    pageSize = GridControl.RowCount < 1000 ? 1000 : GridControl.RowCount;
                }
     
                // Backup selected pageSize and re-select when re-render grid view
                RowInfo.Tag = pageSize;
     
                GridControl.PageSize = pageSize;
                _elementUnderMouse = null;
            }
     
            protected override void SetContentCore(object value)
            {
                if (_dropDownListElement != null && RowInfo?.Tag != null)
                {
                    this._dropDownListElement.SelectedValue = (int)RowInfo.Tag;
                }
            }
     
            public override bool IsCompatible(GridViewColumn data, object context)
            {
                return context is GridTableHeaderRowElement;
            }
     
            protected override Type ThemeEffectiveType => typeof(GridHeaderCellElement);
        }
     
        public sealed class ActionCellElement : GridDataCellElement
        {
            #region Public Delegates
     
            public delegate void EventHandler(object sender, EventArgs e);
     
            #endregion Public Delegates
     
            #region Public Events
     
            public event EventHandler OnSelectedRecord;
     
            public event EventHandler OnUnSelectedRecord;
     
            #endregion Public Events
     
            #region Private Fields
     
            public GridViewCheckBoxElement CheckBoxElement;
            public RadButtonElement BtnFlag;
            public RadButtonElement BtnTimeCircle;
     
            #endregion Private Fields
     
            private readonly RadOffice2007ScreenTipElement _screenTip;
     
            #region Public Constructors
     
            public ActionCellElement(GridViewColumn column, GridRowElement row) : base(column, row)
            {
                Name = "ActionCell_" + RowIndex;
                Text = string.Empty;
     
                _screenTip = new RadOffice2007ScreenTipElement();
                _screenTip.MainTextLabel.Padding = new Padding(2);
                _screenTip.CaptionLabel.Padding = new Padding(2);
                _screenTip.CaptionLabel.Text = @"<html><color=red>Created Date";
                BtnTimeCircle.ScreenTip = _screenTip;
            }
     
            #endregion Public Constructors
     
            public void SetFlagImage(GridViewRowInfo rowInfo = null)
            {
                if (rowInfo != null)
                {
                    RowInfo = rowInfo;
                }
            }
     
            #region Protected Methods
     
            protected override SizeF ArrangeOverride(SizeF finalSize)
            {
                SizeF size = base.ArrangeOverride(finalSize);
                RectangleF clientRect = GetClientRectangle(finalSize);
                float marginX = 4;
                float width = clientRect.Width - (Children.Count + 1) * 4;
                foreach (RadElement element in this.Children)
                {
                    var btnWidth = width / Children.Count;
                    element.Arrange(new RectangleF(
                            marginX,
                            clientRect.Top + 2,
                            btnWidth,
                            clientRect.Height - 4));
                    marginX += btnWidth + 4;
                }
                return size;
            }
     
            protected override void CreateChildElements()
            {
                BtnFlag = new GridViewButtonElement(GetChildElementName("btnFlag"), Resources.USDA_icon_RedFlag);
     
                BtnTimeCircle = new GridViewButtonElement(GetChildElementName("btnTimeCircle"), Resources.USDA_icon_TimeCircle);
     
                CheckBoxElement = new GridViewCheckBoxElement(GetChildElementName("chkBoxItem"));
                CheckBoxElement.ToggleState = ToggleState.Off;
     
                CheckBoxElement.AutoSizeMode = RadAutoSizeMode.FitToAvailableSize;
                BtnTimeCircle.AutoSizeMode = RadAutoSizeMode.FitToAvailableSize;
                BtnFlag.AutoSizeMode = RadAutoSizeMode.FitToAvailableSize;
     
                Children.Clear();
                Children.Add(CheckBoxElement);
                Children.Add(BtnFlag);
                Children.Add(BtnTimeCircle);
            }
     
            #endregion Protected Methods
     
            #region Private Methods
            private string GetChildElementName(string elementName)
            {
                return elementName;
            }
     
            #endregion Private Methods
        }
     
        public sealed class GridViewCheckBoxElement : RadCheckBoxElement
        {
            public bool MultiSelect { get; set; }
     
            public GridViewCheckBoxElement(string name, string text = null)
            {
                DisplayStyle = DisplayStyle.Text;
                Name = name;
                Text = text;
                Alignment = ContentAlignment.MiddleCenter;
                ShowBorder = false;
                BackColor = Color.White;
                CheckAlignment = ContentAlignment.MiddleCenter;
                TextAlignment = ContentAlignment.MiddleCenter;
                MultiSelect = false;
            }
        }
     
        public sealed class GridViewButtonElement : RadButtonElement
        {
            public GridViewButtonElement(string name, Image image = null, string text = null)
            {
                if (image != null)
                {
                    Image = ResizeImage(image, 25, 25);
                    ImageAlignment = ContentAlignment.MiddleCenter;
                }
     
                DisplayStyle = image != null && string.IsNullOrWhiteSpace(text)
                    ? DisplayStyle.ImageAndText
                    : image != null
                        ? DisplayStyle.Image
                        : DisplayStyle.Text;
     
                Name = name;
                Text = text;
                Alignment = ContentAlignment.MiddleCenter;
                ShowBorder = false;
                BackColor = Color.White;
            }
     
            private Bitmap ResizeImage(Image image, int width, int height)
            {
                var destRect = new Rectangle(0, 0, width, height);
                var destImage = new Bitmap(width, height);
     
                destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
     
                using (var graphics = Graphics.FromImage(destImage))
                {
                    graphics.CompositingMode = CompositingMode.SourceCopy;
                    graphics.CompositingQuality = CompositingQuality.HighQuality;
                    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    graphics.SmoothingMode = SmoothingMode.HighQuality;
                    graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
     
                    using (var wrapMode = new ImageAttributes())
                    {
                        wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                        graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
                    }
                }
     
                return destImage;
            }
        }

    Thanks,

    Paul.

  2. Answer
    Dimitar
    Admin
    Dimitar avatar
    2831 posts

    Posted 03 May 2017 Link to this post

    Hi Paul,

    Thank you for writing.

    In this case, you should create a custom column instead of using the CreateRow event. I have attached an example that shows this approach. In addition, I have overridden the IsCompatible method and the ThemeEffectiveType property.

    I hope this will be useful. Let me know if you have additional questions.

    Regards,
    Dimitar
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Paul
    Paul avatar
    34 posts
    Member since:
    Apr 2017

    Posted 03 May 2017 in reply to Dimitar Link to this post

    Hi Dimitar,

    Thank for your helping,

    In your example, i want to add more events for "ActionCellElement" like the picture below, there events will be invoke from "ActionCellElement", what i need to do?

    Thanks,

    Paul.

  4. Answer
    Dimitar
    Admin
    Dimitar avatar
    2831 posts

    Posted 03 May 2017 Link to this post

    Hi Paul,

    You can add the events to the custom column class:
    public class CustomColumn : GridViewDataColumn
    {
        public CustomColumn(string fieldName) : base(fieldName, fieldName)
        {
        }
        public event EventHandler MyEvent;
     
        public void OnMyEvent(EventArgs e)
        {
            if (MyEvent != null)
            {
                MyEvent(this, e);
            }
        }
        public override Type GetCellType(GridViewRowInfo row)
        {
            if (row is GridViewDataRowInfo)
            {
                return typeof(ActionCellElement);
            }
            return base.GetCellType(row);
        }
    }

    Then raise them from the cell element:
    //ActionCellElement class
    private void BtnTimeCircle_Click(object sender, EventArgs e)
    {
        var col = this.ColumnInfo as CustomColumn;
        col.OnMyEvent(new EventArgs());
    }

    Should you have any other questions do not hesitate to ask.

    Regards,
    Dimitar
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  5. Paul
    Paul avatar
    34 posts
    Member since:
    Apr 2017

    Posted 03 May 2017 Link to this post

    Hi Dimitar,

    Thank for your helped, this issue was resolved!

    Thanks,
    Paul

  6. Paul
    Paul avatar
    34 posts
    Member since:
    Apr 2017

    Posted 04 May 2017 Link to this post

    Hi Dimitar,

    I want to know when cell element created, because i need passing some data into cell element and execute some functions from cell. What i need to do?

    Thanks,
    Paul

  7. Dimitar
    Admin
    Dimitar avatar
    2831 posts

    Posted 09 May 2017 Link to this post

    Hi Paul,

    The grid is using UI Virtualization which means that cell elements are created only for the currently visible cells. This is why the elements are not suitable for storing any data. This can be achieved by using the Tag property of each cell (GridViewCellInfo).

    First, you can set it when adding the rows: 
    GridViewDataRowInfo rowInfo = new GridViewDataRowInfo(radGridView1.MasterView);
    rowInfo.Height = 40;
    rowInfo.Cells[0].Tag = "Test " + k;

    Then you can use it when the cell element is attached to the grid:
    public override void Attach(GridViewColumn data, object context)
    {
        base.Attach(data, context);
        if (this.RowInfo.Cells[this.ColumnInfo.Name].Tag == null)
        {
            return;
        }
      
        this.BtnFlag.Text = this.RowInfo.Cells[this.ColumnInfo.Name].Tag.ToString();
    }

    Please let me know if there is something else I can help you with. 
     
    Regards,
    Dimitar
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top