I am using Telerik's RadListView in ListView mode. (latest library)
I am implementing some log window and visually It looks like some chat window, each new log entry is new ListViewDataItem and the window itself is a RadListView.
I do ask it to wrap text in visual item formatting event handler by :
private void OnTextAreaVisualItemFormatting(object sender, ListViewVisualItemEventArgs e)
{
e.VisualItem.TextWrap = true;
}
And I also allow arbitrary item height, since I should be able to display in each list item text of any length.
There is something I have to take care about and I can't figure out how to do it. ListView leaves too much space around text in every visual item. I mean it wraps text fine, but leaves spare 15 pixels on top and at the bottom of each visual item.
I tried to add line
e.VisualItem.Padding = new Padding(0);
to formatting even handler, but it didn't helped.
Do I have any control on VisualItem size, padding while text wrap is enabled? Am I clear?
Regards, Artem
15 Answers, 1 is accepted
Thank you for writing.
I have tried replicating your scenario locally, but I was not able to observe the behavior you described. Please check the attachment to find the sample project I used for testing.
What you have described makes me think that you have set the ItemSpacing property to a value larger than zero. Please try setting the following property:
this
.radListView1.ItemSpacing = 0;
If this still does not help, please send me some code snippets which I can use to reproduce the behavior locally. This will help me investigate the case and provide you with proper support.
In case you have any further questions, do not hesitate to write back.
Kind regards,
Ivan Todorov
the Telerik team
Take your application, that you have sent to me, and set ListView's Dock property to Fill. That is what I have in my application. And then try to resize the form. This is absolutely normal user's action in my application, I allow user to change the layout of tools in my form. After resize you will see the issue described in my first post. Items being stretched get spare space at the top and bottom. I need them to take exactly text's height always.
By the way, ItemSpacing is set to zero, didn't miss it from the beginning. Still need your help :(
Regards, Artem.
Generally each log message should be presented with time stamp and message text, coloured according to message type. Message text can have any length and therefore have to be wrapped to as many lines as needed. I don't want to see horizontal scroll bar on my list no matter how I will resize the tab, containing my list.
here is a class for my visual item:
class TracerListElement : IconListViewVisualItem
{
private Color _warningColor = Color.Blue;
private Color _errorColor = Color.Red;
private Color _regularColor = Color.Black;
private Color _timeStampColor = Color.Black;
private readonly Font _warningFont = new Font("Tahoma", 9, FontStyle.Bold, GraphicsUnit.Point);
private readonly Font _errorFont = new Font("Tahoma", 9, FontStyle.Bold, GraphicsUnit.Point);
private readonly Font _regularFont = new Font("Tahoma", 9, FontStyle.Bold, GraphicsUnit.Point);
private LightVisualElement _timeStamp;
private LightVisualElement _messageText;
private StackLayoutPanel _stackLayout;
protected override void CreateChildElements()
{
base.CreateChildElements();
_stackLayout = new StackLayoutPanel { Orientation = Orientation.Horizontal };
_timeStamp = new LightVisualElement();
_messageText = new LightVisualElement();
_stackLayout.Children.Add(_timeStamp);
_stackLayout.Children.Add(_messageText);
Children.Add(_stackLayout);
BorderBoxStyle = BorderBoxStyle.FourBorders;
BorderBottomWidth = 1;
BorderLeftWidth = BorderRightWidth = BorderTopWidth = 0;
BorderColor = Color.Blue;
BorderGradientStyle = GradientStyles.Solid;
DrawBorder = true;
GradientStyle = GradientStyles.Solid;
}
protected override void SynchronizeProperties()
{
var msg = (TraceMessage) Data.DataBoundItem;
_timeStamp.Text = msg.TimeStamp;
_timeStamp.ForeColor = _timeStampColor;
_stackLayout.AutoSize = true;
_stackLayout.AutoSizeMode = RadAutoSizeMode.Auto;
_messageText.AutoSize = true;
_messageText.AutoSizeMode = RadAutoSizeMode.Auto;
switch (msg.Type)
{
case MessageTypes.Information:
_messageText.ForeColor = _regularColor;
_messageText.Font = _regularFont;
break;
case MessageTypes.Warning:
_messageText.ForeColor = _warningColor;
_messageText.Font = _warningFont;
break;
case MessageTypes.Error:
_messageText.ForeColor = _errorColor;
_messageText.Font = _errorFont;
break;
}
_messageText.Text = msg.MessageText;
_messageText.TextWrap = true;
}
}
And here are few functions connected to RadListView in my user control class:
private RadListView _textArea;
private List<
ListViewDataItem
> _messages;
private void InitializeListView()
{
_textArea = new RadListView
{
AllowEdit = false,
AllowRemove = false,
AutoScroll = false,
AutoSize = false,
BackColor = _backgroundColor,
ShowCheckBoxes = false,
ShowGroups = false,
ShowItemToolTips = false,
Dock = DockStyle.Fill,
ViewType = ListViewType.ListView,
AllowArbitraryItemHeight = true,
AllowArbitraryItemWidth = false,
HotTracking = true,
ItemSpacing = 0
};
_textArea.VisualItemFormatting += OnTextAreaVisualItemFormatting;
_textArea.VisualItemCreating += OnTextAreaVisualItemCreating;
pnlPlaceholder.Controls.Add(_textArea);
}
private void OnTextAreaVisualItemFormatting(object sender, ListViewVisualItemEventArgs e)
{
e.VisualItem.TextWrap = true;
}
void OnTextAreaVisualItemCreating(object sender, ListViewVisualItemCreatingEventArgs e)
{
e.VisualItem = new TracerListElement();
}
And finally here is my message class:
public enum MessageTypes { Warning, Error, Information }
public class TraceMessage
{
public MessageTypes Type { get; set; }
public string MessageText { get; set; }
public string TimeStamp { get; set; }
}
Don't hesitate to ask me more details if you need.
Thanks in advance!
Artem
I was able to observe this behavior when I set the Dock to Fill. In this case you need to change the Width of the ItemSize dynamically when the size of the list view changes. Please refer to the attached project for additional information.
I have also incorporated your custom visual item in the sample project. There are a few things I have modified. First, I have changed the StackLayoutPanel you used in the custom visual items with a WrapLayoutPanel since the StackLayoutPanel cannot wrap its elements. I have also moved all the property settings to the visual item's constructor because all values that are set inside CreateChildElements are considered as default ones and can be overridden by the theme settings.
I hope this will help you. Please let me know if you need further assistance or if you have any additional questions.
Regards,
Ivan Todorov
the Telerik team
I have two issues, both are observable when you have more list items than can be visible in listview, in other words you have to have many items and vertical scroll bar.
1) Just add items to list view so that the scroll bar starts to be visible, and you can see, that the last item is only partially visible. If you try to drag the scroll bar down, you will notice, that it is already in the lowest position, and you still can't see the lowest item.
2) This makes me worry even more, try to create many items, so that their summary height will be at list 3 times the height of the list view.
Now drag the scroll bar up and down many times. First of all I notice that the scroll bar itself changes it's size. And what is even worse - after 2-3 drags you will notice that the lowest items are not visible at all now, and the more times you will drag the scroll bar more items will go below visible lower bound of the list view.
The code below is the code of my user control, that contains the list view:
public
partial
class
TracerOutput : UserControl
{
public
TracerOutput()
{
InitializeComponent();
_messages =
new
List<ListViewDataItem>();
_visibleMessages =
new
List<ListViewDataItem>();
InitializeListView();
_isErrorsVisible = _isRegularsVisible = _isWarningsVisible =
true
;
}
#region Members
private
string
_defaultSaveLogPath =
"C:\\"
;
private
Color _warningColor = Color.Blue;
private
Color _errorColor = Color.Red;
private
Color _informationColor = Color.Black;
private
Color _timeStampColor = Color.Green;
private
Font _warningFont =
new
Font(
"Tahoma"
, 9, FontStyle.Bold, GraphicsUnit.Point);
private
Font _errorFont =
new
Font(
"Tahoma"
, 9, FontStyle.Bold, GraphicsUnit.Point);
private
Font _informationFont =
new
Font(
"Tahoma"
, 9, FontStyle.Bold, GraphicsUnit.Point);
private
Font _timeStampFont =
new
Font(
"Tahoma"
, 9, FontStyle.Bold, GraphicsUnit.Point);
public
Action ErrorMessageDisplayed;
private
Color _backgroundColor = Color.White;
private
bool
_isErrorsVisible, _isWarningsVisible, _isRegularsVisible;
private
RadListView _textArea;
private
List<ListViewDataItem> _messages;
// All messages that tracer have from logger
private
List<ListViewDataItem> _visibleMessages;
// Messages that should be displayed according to user's filtering
private
bool
_scrollToLast =
true
;
#endregion
#region Properties
private
List<TraceMessage.MessageTypes> VisibleMessageTypes
{
get
{
var visibleTypes =
new
List<TraceMessage.MessageTypes>();
if
(_isErrorsVisible)
visibleTypes.Add(TraceMessage.MessageTypes.Error);
if
(_isWarningsVisible)
visibleTypes.Add(TraceMessage.MessageTypes.Warning);
if
(_isRegularsVisible)
visibleTypes.Add(TraceMessage.MessageTypes.Information);
return
visibleTypes;
}
}
/// <summary>
/// Get/Set the default folder path for saving log to textual file
/// </summary>
[Browsable(
true
),
Category(
"SpecialProperties"
),
Description(
"Default folder for saving log files"
),
DefaultValue(
"C:\\"
)]
public
string
SaveLogDefaultPath
{
get
{
return
_defaultSaveLogPath; }
set
{
_defaultSaveLogPath = value;
Invalidate();
}
}
/// <summary>
/// Get/Set tracer background color
/// </summary>
[Browsable(
true
),
Category(
"SpecialProperties"
),
Description(
"Tracer background color"
),
DefaultValue(
typeof
(Color),
"White"
)]
public
Color BackgroundColor
{
get
{
return
_backgroundColor; }
set
{
_backgroundColor = value;
Invalidate();
}
}
/// <summary>
/// Get/Set warning message text color
/// </summary>
[Browsable(
true
),
Category(
"SpecialProperties"
),
Description(
"Warning messages text color"
),
DefaultValue(
typeof
(Color),
"Blue"
)]
public
Color WarningColor
{
get
{
return
_warningColor; }
set
{
_warningColor = value;
Invalidate();
}
}
/// <summary>
/// Get/Set error message text color
/// </summary>
[Browsable(
true
),
Category(
"SpecialProperties"
),
Description(
"Error messages text color"
),
DefaultValue(
typeof
(Color),
"Red"
)]
public
Color ErrorColor
{
get
{
return
_errorColor; }
set
{
_errorColor = value;
Invalidate();
}
}
/// <summary>
/// Get/Set information message text color
/// </summary>
[Browsable(
true
),
Category(
"SpecialProperties"
),
Description(
"Information messages text color"
),
DefaultValue(
typeof
(Color),
"Black"
)]
public
Color InfoColor
{
get
{
return
_informationColor; }
set
{
_informationColor = value;
Invalidate();
}
}
/// <summary>
/// Get/Set time stamp font color
/// </summary>
[Browsable(
true
),
Category(
"SpecialProperties"
),
Description(
"Time stamp font color"
),
DefaultValue(
typeof
(Color),
"Green"
)]
public
Color TimeStampColor
{
get
{
return
_timeStampColor; }
set
{
_timeStampColor = value;
Invalidate();
}
}
/// <summary>
/// Get/Set warning message text font
/// </summary>
[Browsable(
true
),
Category(
"SpecialProperties"
),
Description(
"Warning messages text font"
),
DefaultValue(
typeof
(Font),
"Tahoma, 9pt,style=Bold"
)]
public
Font WarningFont
{
get
{
return
_warningFont; }
set
{
_warningFont = value;
Invalidate();
}
}
/// <summary>
/// Get/Set error message text font
/// </summary>
[Browsable(
true
),
Category(
"SpecialProperties"
),
Description(
"Error messages text font"
),
DefaultValue(
typeof
(Font),
"Tahoma, 9pt,style=Bold"
)]
public
Font ErrorFont
{
get
{
return
_errorFont; }
set
{
_errorFont = value;
Invalidate();
}
}
/// <summary>
/// Get/Set information message text font
/// </summary>
[Browsable(
true
),
Category(
"SpecialProperties"
),
Description(
"Information messages text font"
),
DefaultValue(
typeof
(Font),
"Tahoma, 9pt,style=Bold"
)]
public
Font InfoFont
{
get
{
return
_informationFont; }
set
{
_informationFont = value;
Invalidate();
}
}
/// <summary>
/// Get/Set time stamp font
/// </summary>
[Browsable(
true
),
Category(
"SpecialProperties"
),
Description(
"Time stamp font"
),
DefaultValue(
typeof
(Font),
"Tahoma, 9pt,style=Bold"
)]
public
Font TimeStampFont
{
get
{
return
_timeStampFont; }
set
{
_timeStampFont = value;
Invalidate();
}
}
#endregion
#region Methods
private
void
InitializeListView()
{
_textArea =
new
RadListView
{
AllowEdit =
false
,
AllowRemove =
false
,
AutoScroll =
true
,
AutoSize =
false
,
BackColor = BackgroundColor,
ShowCheckBoxes =
false
,
ShowGroups =
false
,
ShowItemToolTips =
false
,
Dock = DockStyle.Fill,
ViewType = ListViewType.ListView,
AllowArbitraryItemHeight =
true
,
AllowArbitraryItemWidth =
false
,
HotTracking =
true
,
ItemSpacing = 0,
HorizontalScrollState = ScrollState.AlwaysHide,
VerticalScrollState = ScrollState.AutoHide
};
_textArea.VisualItemFormatting += OnTextAreaVisualItemFormatting;
_textArea.VisualItemCreating += OnTextAreaVisualItemCreating;
_textArea.SizeChanged += OnTextAreaSizeChanged;
pnlPlaceholder.Controls.Add(_textArea);
}
private
List<ListViewDataItem> GetVisibleItems()
{
return
_messages.FindAll(m => (((TraceMessage)m.Tag).Type == TraceMessage.MessageTypes.Warning && _isWarningsVisible) ||
(((TraceMessage)m.Tag).Type == TraceMessage.MessageTypes.Error && _isErrorsVisible) ||
(((TraceMessage)m.Tag).Type == TraceMessage.MessageTypes.Information && _isRegularsVisible));
}
private
void
RedrawMessages()
{
_textArea.Items.Clear();
_visibleMessages = GetVisibleItems();
_textArea.BeginUpdate();
_textArea.Items.AddRange(_visibleMessages.ToArray());
_textArea.EndUpdate();
}
public
void
SaveLogToFile(
bool
isOnlyVisible)
{
const
string
logFilter =
"Log files (*.txt)|*.txt"
;
const
string
logFileExt =
"txt"
;
const
string
dialogTitle =
"Export program log to file ..."
;
var saveLogDialog = GetSaveFileDialog(dialogTitle, logFilter, logFileExt);
if
(DialogResult.OK == saveLogDialog.ShowDialog())
{
var visibleTypes = isOnlyVisible
? VisibleMessageTypes
: Enum.GetValues(
typeof
(TraceMessage.MessageTypes)).Cast<TraceMessage.MessageTypes>().ToList();
if
(SaveToFileRequested !=
null
)
SaveToFileRequested(saveLogDialog.FileName, visibleTypes);
}
}
private
SaveFileDialog GetSaveFileDialog(
string
title,
string
filter,
string
defaultExtension)
{
var saveFileDialog =
new
SaveFileDialog
{
InitialDirectory = SaveLogDefaultPath,
Title = title,
Filter = filter,
CreatePrompt =
false
,
CheckFileExists =
false
,
CheckPathExists =
false
,
AutoUpgradeEnabled =
true
,
SupportMultiDottedExtensions =
false
,
OverwritePrompt =
true
,
DefaultExt = defaultExtension,
AddExtension =
true
};
return
saveFileDialog;
}
#endregion
#region Event Handlers
#region Context menu
private
void
OnToggleErrorMessagesClick(
object
sender, EventArgs e)
{
_isErrorsVisible = !_isErrorsVisible;
RedrawMessages();
}
private
void
OnToggleWarningMessagesClick(
object
sender, EventArgs e)
{
_isWarningsVisible = !_isWarningsVisible;
RedrawMessages();
}
private
void
OnToggleRegularMessagesClick(
object
sender, EventArgs e)
{
_isRegularsVisible = !_isRegularsVisible;
RedrawMessages();
}
private
void
OnContextMenuOpenning(
object
sender, CancelEventArgs e)
{
warningsVisibleToolStripMenuItem.Checked = _isWarningsVisible;
errorsVisibleToolStripMenuItem.Checked = _isErrorsVisible;
messagesVisibleToolStripMenuItem.Checked = _isRegularsVisible;
scrollToLastToolStripMenuItem.Checked = _scrollToLast;
copyThisMessageToolStripMenuItem.Visible = (_textArea.SelectedItem !=
null
);
}
private
void
OnClearLogClick(
object
sender, EventArgs e)
{
if
(ClearRequested !=
null
)
ClearRequested();
}
private
void
OnSaveAllToFileClick(
object
sender, EventArgs e)
{
SaveLogToFile(
false
);
}
private
void
OnSaveToClipboardClick(
object
sender, EventArgs e)
{
if
(SaveToClipboardRequested !=
null
)
SaveToClipboardRequested(VisibleMessageTypes);
}
private
void
OnSaveVisibleOnlyToFileClick(
object
sender, EventArgs e)
{
SaveLogToFile(
true
);
}
private
void
OnScrollToLastClick(
object
sender, EventArgs e)
{
_scrollToLast = !_scrollToLast;
}
private
void
OnCopySelectedMessageClick(
object
sender, EventArgs e)
{
var temp = _textArea.SelectedItem;
if
(temp !=
null
)
{
var text = ((TraceMessage)temp.Tag).MessageText;
Clipboard.SetText(text);
}
}
#endregion
#region ListView
void
OnTextAreaSizeChanged(
object
sender, EventArgs e)
{
_textArea.ItemSize =
new
Size(_textArea.Width - _textArea.ListViewElement.ViewElement.VScrollBar.Size.Width, 0);
}
private
void
OnTextAreaVisualItemFormatting(
object
sender, ListViewVisualItemEventArgs e)
{
e.VisualItem.TextWrap =
true
;
}
void
OnTextAreaVisualItemCreating(
object
sender, ListViewVisualItemCreatingEventArgs e)
{
e.VisualItem =
new
TracerListElement(WarningColor, ErrorColor, InfoColor, TimeStampColor, WarningFont, ErrorFont, InfoFont, TimeStampFont);
}
#endregion
protected
override
void
OnPaint(PaintEventArgs e)
{
base
.OnPaint(e);
_textArea.ItemSize =
new
Size(_textArea.Width - _textArea.ListViewElement.ViewElement.VScrollBar.Size.Width, 0);
}
#endregion
#region ITracerUIControl Implementation
public
event
Action ClearRequested;
public
event
Action<List<TraceMessage.MessageTypes>> SaveToClipboardRequested;
public
event
Action<
string
, List<TraceMessage.MessageTypes>> SaveToFileRequested;
public
void
AppendMessages(TraceMessage[] messages)
{
if
(InvokeRequired)
{
BeginInvoke(
new
Action<TraceMessage[]>(AppendMessages),
new
object
[] { messages });
return
;
}
var messagesNumber = messages.Length;
var newMessages =
new
List<ListViewDataItem>(messagesNumber);
var newVisibleMessages =
new
List<ListViewDataItem>();
for
(
int
i = 0; i < messagesNumber; i++)
{
var msg = messages[i].Copy();
var temp =
new
ListViewDataItem();
temp.Tag = msg;
temp.DataBoundItem = msg;
switch
(msg.Type)
{
case
TraceMessage.MessageTypes.Information:
temp.ForeColor = InfoColor;
temp.Font = InfoFont;
break
;
case
TraceMessage.MessageTypes.Warning:
temp.ForeColor = WarningColor;
temp.Font = WarningFont;
break
;
case
TraceMessage.MessageTypes.Error:
temp.ForeColor = ErrorColor;
temp.Font = ErrorFont;
break
;
}
newMessages.Add(temp);
if
(VisibleMessageTypes.Contains(msg.Type))
newVisibleMessages.Add(temp);
}
_messages.AddRange(newMessages);
_visibleMessages.AddRange(newVisibleMessages);
if
(_visibleMessages.Count > 0)
{
_textArea.BeginUpdate();
_textArea.Items.AddRange(newVisibleMessages.ToArray());
var lastIndex = _textArea.Items.Count - 1;
if
(_scrollToLast)
_textArea.SelectedItem = _textArea.Items[lastIndex];
_textArea.EndUpdate();
}
}
public
void
ClearLog()
{
_isErrorsVisible = _isRegularsVisible = _isWarningsVisible =
true
;
_messages.Clear();
_textArea.Items.Clear();
}
#endregion
class
TracerListElement : IconListViewVisualItem
{
public
TracerListElement(Color warningColor, Color errorColor, Color infoColor, Color timeMarkColor, Font warningFont, Font errorFont, Font infoFont, Font timeMarkFont)
{
_warningColor = warningColor;
_errorColor = errorColor;
_infoColor = infoColor;
_timeStampColor = timeMarkColor;
_warningFont = warningFont;
_errorFont = errorFont;
_infoFont = infoFont;
_timeMarkFont = timeMarkFont;
DrawBorder =
false
;
GradientStyle = GradientStyles.Solid;
}
#region Members
private
Color _warningColor;
private
Color _errorColor;
private
Color _infoColor;
private
Color _timeStampColor;
private
readonly
Font _warningFont;
private
readonly
Font _errorFont;
private
readonly
Font _infoFont;
private
readonly
Font _timeMarkFont;
private
LightVisualElement _timeStamp;
private
LightVisualElement _messageText;
private
LightVisualElement _link;
private
WrapLayoutPanel _stackLayout;
private
WrapLayoutPanel _linkStackLayout;
#endregion
protected
override
void
CreateChildElements()
{
base
.CreateChildElements();
_stackLayout =
new
WrapLayoutPanel { Orientation = Orientation.Horizontal, AutoSize =
true
, AutoSizeMode = RadAutoSizeMode.Auto };
_linkStackLayout =
new
WrapLayoutPanel { Orientation = Orientation.Vertical, AutoSize =
true
, AutoSizeMode = RadAutoSizeMode.Auto };
_timeStamp =
new
LightVisualElement { TextAlignment = ContentAlignment.TopLeft };
_messageText =
new
LightVisualElement { TextWrap =
true
, TextAlignment = ContentAlignment.TopLeft, AutoSize =
true
, AutoSizeMode = RadAutoSizeMode.Auto };
_link =
new
LightVisualElement { TextWrap =
true
, TextAlignment = ContentAlignment.TopLeft, ClickMode = ClickMode.Press };
_linkStackLayout.Children.Add(_messageText);
_linkStackLayout.Children.Add(_link);
_stackLayout.Children.Add(_timeStamp);
_stackLayout.Children.Add(_linkStackLayout);
Children.Add(_stackLayout);
}
//We override this property to erase unnecessary text that is displayed on custom item
public
override
string
Text
{
get
{
return
null
;
}
set
{
base
.Text = value;
}
}
protected
override
void
SynchronizeProperties()
{
base
.SynchronizeProperties();
// Let the base handle all hover/enter/selected events and efects
#region Forward child-element's mouse events to custom list item object
_timeStamp.ShouldHandleMouseInput =
false
;
_timeStamp.NotifyParentOnMouseInput =
true
;
_messageText.ShouldHandleMouseInput =
false
;
_messageText.NotifyParentOnMouseInput =
true
;
_link.ShouldHandleMouseInput =
true
;
_link.NotifyParentOnMouseInput =
true
;
_stackLayout.ShouldHandleMouseInput =
false
;
_stackLayout.NotifyParentOnMouseInput =
true
;
_linkStackLayout.ShouldHandleMouseInput =
false
;
_linkStackLayout.NotifyParentOnMouseInput =
true
;
NotifyParentOnMouseInput =
true
;
ShouldHandleMouseInput =
true
;
#endregion
var msg = (TraceMessage)Data.DataBoundItem;
_timeStamp.Text = msg.TimeStamp.ToString(
"HH:mm:ss"
);
_timeStamp.ForeColor = _timeStampColor;
_timeStamp.Font = _timeMarkFont;
switch
(msg.Type)
{
case
TraceMessage.MessageTypes.Information:
_messageText.ForeColor = _infoColor;
_messageText.Font = _infoFont;
break
;
case
TraceMessage.MessageTypes.Warning:
_messageText.ForeColor = _warningColor;
_messageText.Font = _warningFont;
break
;
case
TraceMessage.MessageTypes.Error:
_messageText.ForeColor = _errorColor;
_messageText.Font = _errorFont;
break
;
}
_messageText.Text = msg.MessageText;
_messageText.TextWrap =
true
;
_link.MouseDown -= OnLinkClick;
_link.Text = msg.Link;
_link.Font = _infoFont;
_link.ForeColor = Color.Blue;
if
(!
string
.IsNullOrEmpty(msg.Link))
_link.MouseDown += OnLinkClick;
}
void
OnLinkClick(
object
sender, EventArgs e)
{
Process.Start(((RadItem)sender).AccessibleName);
((RadItem)sender).ForeColor = Color.BlueViolet;
}
protected
override
Type ThemeEffectiveType
{
get
{
// What you return here is actually says how will your custom item behave.
// It will react to selection, hover and so on as Telerik's object of returned type.
return
typeof
(IconListViewVisualItem);
}
}
}
}
The code below is the class that is used as data item for list view visual item:
public
class
TraceMessage
{
public
enum
MessageTypes { Warning, Error, Information }
private
bool
_isTypeSet;
private
MessageTypes _type;
/// <summary>
/// Message type.
/// </summary>
public
MessageTypes Type
{
get
{
return
_isTypeSet ? _type : MessageTypes.Information; }
set
{
_type = value;
_isTypeSet =
true
;
}
}
/// <summary>
/// Message text.
/// </summary>
public
string
MessageText {
get
;
set
; }
/// <summary>
/// Link path.
/// </summary>
public
string
Link {
get
;
set
; }
/// <summary>
/// Time when the tracer got this message.
/// Used by ILoggerManager, no need for explicit value signing.
/// </summary>
public
DateTime TimeStamp {
get
;
set
; }
public
TraceMessage Copy()
{
var msg =
new
TraceMessage { Type = Type, TimeStamp = TimeStamp, Link = Link, MessageText = MessageText };
return
msg;
}
}
I was able to observe the described issues. The reason they are occurring is that you are deriving from the IconListViewVisualItem class and you are using this with the SimpleList view. The IconListViewVisualItem class represents the visual items in IconView mode and has specific measuring logic valid only for the IconView. I am not sure why you have changed this, but in SimpleList mode you should derive from the SimpleListViewVisualItem class:
class
TracerListElement : SimpleListViewVisualItem
{
//...
protected
override
Type ThemeEffectiveType
{
get
{
return
typeof
(SimpleListViewVisualItem);
}
}
}
I hope this will help you. Feel free to ask if you have any additional questions.
Kind regards,
Ivan Todorov
the Telerik team
Thanks, it helped.
So, let me know If I understood you correct. What you say is that for every ListView mode (e.g. Simple, Icons, Details) I have to use corresponding visual item class? Even if my item looks as some simple text in both icons and details view mode?
If in future my list view control will allow to change its mode I have to do something like below?
void
OnTextAreaVisualItemCreating(
object
sender, ListViewVisualItemCreatingEventArgs e)
{
switch
(_textArea.ViewType)
{
case
ListViewType.ListView:
e.VisualItem =
new
MyListViewVisualItem();
break
;
case
ListViewType.IconsView:
e.VisualItem =
new
MyIconViewVisualItem();
break
;
case
ListViewType.DetailsView:
e.VisualItem =
new
MyDetailsViewVisualItem();
break
;
}
}
Yes, the approach you have proposed is correct. Even if the items look similar in the different modes, each item type defines different logic for calculating its size according to the type and the properties of the particular view. As you can see, in SimpleView the items can only be vertically stacked, in IconView the items are arranged continuously in rows and in DetailView each item has a cells container which hold the detail cells.
I hope you find this information useful. Feel free to ask if you have any future questions.
Kind regards,
Ivan Todorov
the Telerik team
Hi guys,
this issue seems to be reproduced again, when changed to IconListViewVisualItem and ListViewType.IconsView
I able to see unexpected spacing between items, which is randomly appear, when minimizing the container (form) to its minimal width.
attached are some screenshots of my problem and here is the reviewed code of the main form:
public
partial
class
Form1 : Form
{
private
BindingList<TraceMessage> _messages;
public
Form1()
{
InitializeComponent();
this
.radListView1.Dock = DockStyle.Fill;
radListView1.ViewType = ListViewType.IconsView;
//TODO: was ListViewType.ListView
this
.radListView1.AllowArbitraryItemHeight =
true
;
_messages =
new
BindingList<TraceMessage>();
for
(
int
i = 0; i < 10; i++)
{
_messages.Add(
new
TraceMessage()
{
MessageText = Guid.NewGuid().ToString() +
" "
+ Guid.NewGuid().ToString(),
Type = MessageTypes.Information,
TimeStamp = DateTime.Now.AddMinutes(i).ToShortTimeString()
});
}
radListView1.DataSource = _messages;
radListView1.DisplayMember =
"MessageText"
;
radListView1.SizeChanged +=
new
EventHandler(radListView1_SizeChanged);
radListView1.HorizontalScrollState = ScrollState.AlwaysHide;
radListView1.VisualItemCreating +=
new
ListViewVisualItemCreatingEventHandler(radListView1_VisualItemCreating);
}
void
radListView1_VisualItemCreating(
object
sender, ListViewVisualItemCreatingEventArgs e)
{
e.VisualItem =
new
TracerListElement();
}
protected
override
void
OnShown(EventArgs e)
{
base
.OnShown(e);
radListView1.ItemSize =
new
Size(
this
.radListView1.Width -
this
.radListView1.ListViewElement.ViewElement.VScrollBar.Size.Width, 0);
}
void
radListView1_SizeChanged(
object
sender, EventArgs e)
{
radListView1.ItemSize =
new
Size(
this
.radListView1.Width -
this
.radListView1.ListViewElement.ViewElement.VScrollBar.Size.Width, 0);
}
private
void
radListView1_VisualItemFormatting(
object
sender, Telerik.WinControls.UI.ListViewVisualItemEventArgs e)
{
e.VisualItem.TextWrap =
true
;
}
}
public
enum
MessageTypes { Warning, Error, Information }
public
class
TraceMessage
{
public
MessageTypes Type {
get
;
set
; }
public
string
MessageText {
get
;
set
; }
public
string
TimeStamp {
get
;
set
; }
}
class
TracerListElement : IconListViewVisualItem
//TODO: was SimpleListViewVisualItem
{
private
Color _warningColor = Color.Blue;
private
Color _errorColor = Color.Red;
private
Color _regularColor = Color.Black;
private
Color _timeStampColor = Color.Black;
private
readonly
Font _warningFont =
new
Font(
"Tahoma"
, 9, FontStyle.Bold, GraphicsUnit.Point);
private
readonly
Font _errorFont =
new
Font(
"Tahoma"
, 9, FontStyle.Bold, GraphicsUnit.Point);
private
readonly
Font _regularFont =
new
Font(
"Tahoma"
, 9, FontStyle.Bold, GraphicsUnit.Point);
private
LightVisualElement _timeStamp;
private
LightVisualElement _messageText;
private
WrapLayoutPanel _stackLayout;
public
TracerListElement()
{
BorderBoxStyle = BorderBoxStyle.FourBorders;
BorderBottomWidth = 1;
BorderLeftWidth = BorderRightWidth = BorderTopWidth = 0;
BorderColor = Color.Blue;
BorderGradientStyle = GradientStyles.Solid;
DrawBorder =
true
;
GradientStyle = GradientStyles.Solid;
}
protected
override
void
CreateChildElements()
{
base
.CreateChildElements();
_stackLayout =
new
WrapLayoutPanel { Orientation = Orientation.Horizontal };
_timeStamp =
new
LightVisualElement();
_timeStamp.TextAlignment = ContentAlignment.TopLeft;
_messageText =
new
LightVisualElement();
_messageText.TextWrap =
true
;
_messageText.TextAlignment = ContentAlignment.TopLeft;
_stackLayout.Children.Add(_timeStamp);
_stackLayout.Children.Add(_messageText);
Children.Add(_stackLayout);
}
protected
override
void
SynchronizeProperties()
{
var msg = (TraceMessage)Data.DataBoundItem;
_timeStamp.Text = msg.TimeStamp;
_timeStamp.ForeColor = _timeStampColor;
_stackLayout.AutoSize =
true
;
_stackLayout.AutoSizeMode = RadAutoSizeMode.Auto;
_messageText.AutoSize =
true
;
_messageText.AutoSizeMode = RadAutoSizeMode.Auto;
switch
(msg.Type)
{
case
MessageTypes.Information:
_messageText.ForeColor = _regularColor;
_messageText.Font = _regularFont;
break
;
case
MessageTypes.Warning:
_messageText.ForeColor = _warningColor;
_messageText.Font = _warningFont;
break
;
case
MessageTypes.Error:
_messageText.ForeColor = _errorColor;
_messageText.Font = _errorFont;
break
;
}
_messageText.Text = msg.MessageText;
_messageText.TextWrap =
true
;
}
protected
override
Type ThemeEffectiveType
{
get
{
return
typeof
(IconListViewVisualItem);
//TODO: was SimpleListViewVisualItem
}
}
}
Just to clarify my post - I got similar issue to what Artem has described previously, I took the example, mentioned here and reviewed it a bit.
so right now, when changing the container size (and Dock property is set to Fill for the RadListView), I can see that some spacing appears between items, therefore the lowest item might become partially visible. I also noticed that more items you add - more spacing you get, which is making the number of items totally invisible.
Any ideas? thanks!
Thank you for writing.
I was not able to reproduce the observed behavior on my end. I have recorded I small video which shows how this works on my side. Could you please check it and let me know what else I need to do in order to reproduce this?
In addition could you specify which the exact version of the suite that you use?
I am looking forward to your reply.
Regards,
Dimitar
Telerik
See What's Next in App Development. Register for TelerikNEXT.
Hi Dimitar,
thank you for prompt response
Telerik version used: 2013.3.1016.20
video with my issue is posted here: https://www.dropbox.com/s/czkoyz9t23aofue/NewFilm_150429193553.avi
Thank you for writing back.
I was able to reproduce the observed issue with the specified suite version. It is connected to an issue that is already resolved and if you upgrade it will not occur.
The workaround I can suggest (for the version that you are using) is to change the ViewType to ListView and inherit SimpleListViewVisualItem instead of IconListViewVisualItem. I have tested this on my side and I cannot see a significant change when this workaround is used.
I hope this helps.
Regards,
Dimitar
Telerik
See What's Next in App Development. Register for TelerikNEXT.