Custom ListView items

7 posts, 1 answers
  1. Tino
    Tino avatar
    86 posts
    Member since:
    Jul 2017

    Posted 29 Jan 2018 Link to this post

    I'm trying to create a ListView with custom items, as shown in the attached image. The lower textbox can be of varying height due to containing more or less text lines.

    I have tried a horizontal StackLayout with three text boxes (RadTextBoxElement). I then use a vertical StackLayout containing the first stacklayout plus a fourth textbox. I have used the sample in the docs as a basis.

    I have the listview type as ListViewType.ListView. I also have AllowArbitraryItemHeight = true.

    I can't get the lower textbox to display larger than a single line, despite containing multiple text lines.

    The custom visual item class is below. In this version I'm actually using a RadLabelElement for the lower item instead of a textbox as it does show relatively ok, but has drawbacks like not being able to select & copy text from it.

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using Telerik.WinControls.Layouts;
    using Telerik.WinControls.UI;
     
    namespace UCStudio.UI
    {
        public class RuleVisualItem : SimpleListViewVisualItem
        {
            private RadTextBoxElement _idElement;
            private RadTextBoxElement _sequenceElement;
            private RadTextBoxElement _nameElement;
            private RadLabelElement _ruleTextElement;
            private LightVisualElement _contentElement;
            private StackLayoutPanel _vStackLayout;
            private StackLayoutPanel _stackLayout;
     
            protected override void CreateChildElements()
            {
                base.CreateChildElements();
     
                _stackLayout = new StackLayoutPanel
                {
                    Orientation = Orientation.Horizontal,
                    //AutoSize = true,
                    EqualChildrenWidth = true,
                    ShouldHandleMouseInput = false,
                    NotifyParentOnMouseInput = true
                };
     
                _vStackLayout = new StackLayoutPanel
                {
                    Orientation = Orientation.Vertical,
                    ShouldHandleMouseInput = false,
                    NotifyParentOnMouseInput = true
                };
     
                _contentElement = new LightVisualElement
                {
                    StretchHorizontally = true,
                    MinSize = new Size(120, 0),
                    ShouldHandleMouseInput = false,
                    NotifyParentOnMouseInput = true
                };
                _idElement = new RadTextBoxElement {Text = ""};
                _idElement.TextBoxItem.ReadOnly = true;
                _stackLayout.Children.Add( _idElement);
     
                _sequenceElement = new RadTextBoxElement {Text = ""};
                _sequenceElement.TextBoxItem.ReadOnly = true;
                _stackLayout.Children.Add( _sequenceElement);
     
                _nameElement = new RadTextBoxElement {Text = ""};
                _nameElement.TextBoxItem.ReadOnly = true;
                _stackLayout.Children.Add( _nameElement);
     
                _stackLayout.Children.Add( _contentElement);
     
                _ruleTextElement = new RadLabelElement
                {
                    Text = "",
                    ShouldHandleMouseInput = false,
                    NotifyParentOnMouseInput = true
                };
     
                _vStackLayout.Children.Add( _stackLayout);
                _vStackLayout.Children.Add( _ruleTextElement);
     
                Children.Add( _vStackLayout);
            }
     
            protected override void SynchronizeProperties()
            {
                base.SynchronizeProperties();
     
                Text = "";
                _contentElement.Text = "";
                _idElement.Text = Convert.ToString( Data["RuleItemId"]);
                _sequenceElement.Text = Convert.ToString( Data["Sequence"]);
                _nameElement.Text = Convert.ToString( Data["Name"]);
                _ruleTextElement.Text = Convert.ToString( Data["RuleItemText"]);
            }
     
            protected override Type ThemeEffectiveType => typeof(SimpleListViewVisualItem);
        }
    }

     

    Also I don't know why I need to use the LightVisualElement _contentElement; If I remove this the textboxes in the horizontal stacklayout show as minimal size.

    Another thing is I need the third textbox in the top group to be of varying size, i.e. to fit itself to its content but it isn't, because of EqualChildrenWidth = true (which I need or the textboxes show as tiny, again).

    I'm struggling to find the correct combination of techniques to achieve the above. Any help appreciated.

     

     

  2. Answer
    Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3754 posts

    Posted 30 Jan 2018 Link to this post

    Hello, Tino,

    Thank you for writing.  

    The described approach for creating your custom visual items in RadListView is correct. For the LightVisualElement in the horizontal stack you specify the minimum size. However, for the text boxes you don't specify the size. That is why when you comment the code for adding the LightVisualElement, the text boxes are shrunk. It is necessary to specify some size for the text boxes. I have modified the code snippet and replaced the RadLabelElement with a RadTextBoxControlElement instead of RadTextBoxElement. Set the Multiline property to true in order to show more than one row of the text. Note that RadTextBoxElement hosts the standard MS TextBox. Using controls in your custom items may slow down the scrolling and will cause visual glitches as they do not support clipping. It is better using elements as RadTextBoxControlElement. I have prepared a sample project for your reference where I have modified the sample code. 



    I hope this information helps. Should you have further questions I would be glad to help. 
     
     Regards,
    Dess
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Tino
    Tino avatar
    86 posts
    Member since:
    Jul 2017

    Posted 30 Jan 2018 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    Thanks, that pretty much covered everything.
  4. Tino
    Tino avatar
    86 posts
    Member since:
    Jul 2017

    Posted 05 Feb 2018 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    How do I retrieve the custom items back again, for e.g. if I want to highlight some text in one of the RadTextBoxElements? 
  5. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3754 posts

    Posted 06 Feb 2018 Link to this post

    Hello, Tino,  

    Thank you for writing back. 

    RadTextBoxControlElement allows you customizing the text color by setting the ForeColor property. However, it is not possible to customize different parts of the text in a different color. 

    Note that you can use a RadLabelElement instead and use the built-in HTML-like text formatting functionality. Telerik UI for for WinForms provide an advanced text styling mechanism which can be applied to all Telerik WinForms controls and their elements, because it enhances one of the smallest element in Telerik Presentation Framework - the text primitive. The new rich text formatting mechanism uses plain HTML tags to display formatted text such as font style, font color, font size, etc.

    Here is the modified custom SimpleListViewVisualItem which result is illustrated in the screenshot below: 
    public class RuleVisualItem : SimpleListViewVisualItem
    {
        private RadTextBoxControlElement _idElement;
        private RadTextBoxControlElement _sequenceElement;
        private RadTextBoxControlElement _nameElement;
        private RadLabelElement _ruleTextElement;
        private LightVisualElement _contentElement;
        private StackLayoutPanel _vStackLayout;
        private StackLayoutPanel _stackLayout;
     
        protected override void CreateChildElements()
        {
            base.CreateChildElements();
     
            _stackLayout = new StackLayoutPanel
            {
                Orientation = Orientation.Horizontal,
                EqualChildrenWidth = true,
                ShouldHandleMouseInput = false,
                NotifyParentOnMouseInput = true
            };
     
            _vStackLayout = new StackLayoutPanel
            {
                Orientation = Orientation.Vertical,
                ShouldHandleMouseInput = false,
                NotifyParentOnMouseInput = true
            };
     
            _contentElement = new LightVisualElement
            {
                StretchHorizontally = true,
                MinSize = new Size(120, 0),
                ShouldHandleMouseInput = false,
                NotifyParentOnMouseInput = true
            };
            _idElement = new RadTextBoxControlElement { Text = "", MinSize = new Size(120, 0) };
            _idElement.IsReadOnly = true;
            _stackLayout.Children.Add(_idElement);
     
            _sequenceElement = new RadTextBoxControlElement { Text = "" };
            _sequenceElement.IsReadOnly = true;
            _stackLayout.Children.Add(_sequenceElement);
     
            _nameElement = new RadTextBoxControlElement { Text = "" };
            _nameElement.IsReadOnly = true;
            _stackLayout.Children.Add(_nameElement);
     
            _ruleTextElement = new RadLabelElement
            {
                Text = "",
                TextWrap = true
            };
     
            _vStackLayout.Children.Add(_stackLayout);
            _vStackLayout.Children.Add(_ruleTextElement);
     
            Children.Add(_vStackLayout);
        }
     
        protected override void SynchronizeProperties()
        {
            base.SynchronizeProperties();
     
            Text = "";
            _contentElement.Text = "";
            _idElement.Text = Convert.ToString(Data["RuleItemId"]);
            _sequenceElement.Text = Convert.ToString(Data["Sequence"]);
            _nameElement.Text = Convert.ToString(Data["Name"]);
            string[] tokens = Convert.ToString(Data["RuleItemText"]).Split(new string[] { "." },
                StringSplitOptions.RemoveEmptyEntries);
          
            Color[] colors = new Color[]
            {
                Color.Blue, Color.Green, Color.Fuchsia,
                Color.Red, Color.Orange, Color.Pink, Color.Purple, Color.Peru, Color.PowderBlue
            };
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < tokens.Length; i++)
            {
                sb.Append("<color="+colors[i%colors.Length].Name.ToLower()+">"+tokens[i]);
            }
            
            _ruleTextElement.Text = "<html><color=red>" + sb.ToString() ;
        }
     
        protected override Type ThemeEffectiveType
        {
            get
            {
                return typeof(SimpleListViewVisualItem);
            }
        }
    }



    I hope this information helps. If you have any additional questions, please let me know. 

     Regards,
    Dess
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  6. Tino
    Tino avatar
    86 posts
    Member since:
    Jul 2017

    Posted 06 Feb 2018 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    Thanks, that highlighting method should be fine but if you recall I originally used a RadLabelElement and one problem with that was that I also need to be able to select and copy text from the control. Is there an easy way to do this with a RadLabelElement?
  7. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3754 posts

    Posted 07 Feb 2018 Link to this post

    Hello, Tino,  

    Thank you for writing back. 

    Indeed, selection in the label element is not supported. On the other hand, the HTML-like text formatting is not supported in the text box element. Note that both requirements are not so easy functionalities to be supported in one element. The only possible solution that I can suggest you to have formatted text with selection is to use a RadRichTextEditor hosted in a RadHostItem for the custom visual items. 

    I hope this information helps. If you have any additional questions, please let me know. 

     Regards,
    Dess
    Progress Telerik
    Try our brand new, jQuery-free Angular 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