589 lines
23 KiB
C#
589 lines
23 KiB
C#
#if (FRAMEWORK20)
|
|
using System;
|
|
using System.Text;
|
|
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
using System.Drawing.Drawing2D;
|
|
using System.ComponentModel;
|
|
|
|
namespace DevComponents.DotNetBar
|
|
{
|
|
/// <summary>
|
|
/// Represents an item that displays log information in list container.
|
|
/// </summary>
|
|
public class LogItem : BaseItem
|
|
{
|
|
#region Private Variables
|
|
private const int DefaultWidth = 96;
|
|
private const int VerticalPadding = 3;
|
|
private const int HorizontalPadding = 7;
|
|
private const int TextLineSpacing = 4;
|
|
private const int MinimumHeight = 32;
|
|
private Size _CalloutSize = new Size(10, 10);
|
|
private int _CornerSize = 5;
|
|
#endregion
|
|
|
|
#region Events
|
|
/// <summary>
|
|
/// Occurs when text markup link is clicked. Markup links can be created using "a" tag, for example:
|
|
/// <a name="MyLink">Markup link</a>
|
|
/// </summary>
|
|
public event MarkupLinkClickEventHandler MarkupLinkClick;
|
|
#endregion
|
|
|
|
#region Internal Implementation
|
|
/// <summary>
|
|
/// Initializes a new instance of the LogItem class.
|
|
/// </summary>
|
|
/// <param name=""></param>
|
|
public LogItem():this("","")
|
|
{
|
|
}
|
|
/// <summary>
|
|
/// Creates new instance of LogItem and assigns the name to it.
|
|
/// </summary>
|
|
/// <param name="sItemName">Item name.</param>
|
|
public LogItem(string sItemName):this(sItemName,"") {}
|
|
/// <summary>
|
|
/// Creates new instance of LogItem and assigns the name and text to it.
|
|
/// </summary>
|
|
/// <param name="sItemName">Item name.</param>
|
|
/// <param name="ItemText">item text.</param>
|
|
public LogItem(string sItemName, string ItemText)
|
|
: base(sItemName, ItemText)
|
|
{
|
|
SetIsContainer(true);
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (BarUtilities.DisposeItemImages && !this.DesignMode)
|
|
{
|
|
BarUtilities.DisposeImage(ref _Image);
|
|
}
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns copy of the item.
|
|
/// </summary>
|
|
public override BaseItem Copy()
|
|
{
|
|
LogItem copy = new LogItem(m_Name);
|
|
this.CopyToItem(copy);
|
|
return copy;
|
|
}
|
|
/// <summary>
|
|
/// Copies the ButtonItem specific properties to new instance of the item.
|
|
/// </summary>
|
|
/// <param name="copy">New ButtonItem instance.</param>
|
|
protected override void CopyToItem(BaseItem instanceCopy)
|
|
{
|
|
LogItem copy = instanceCopy as LogItem;
|
|
base.CopyToItem(instanceCopy);
|
|
|
|
copy.BackColor = this.BackColor;
|
|
copy.Created = this.Created;
|
|
copy.HeaderTextColor = this.HeaderTextColor;
|
|
if (this.Image != null)
|
|
copy.Image = (Image) this.Image.Clone();
|
|
copy.ImagePosition = this.ImagePosition;
|
|
copy.SourceName = this.SourceName;
|
|
copy.TextColor = this.TextColor;
|
|
}
|
|
|
|
public override BaseItem ItemAtLocation(int x, int y)
|
|
{
|
|
if (this.SubItems.Count > 0)
|
|
{
|
|
BaseItem item = base.ItemAtLocation(x, y);
|
|
if (item != null) return item;
|
|
}
|
|
return this.Bounds.Contains(x, y) ? this : null;
|
|
}
|
|
|
|
protected virtual int GetTextWidth(Rectangle bounds)
|
|
{
|
|
int textWidth = Math.Max(0, bounds.Width - (HorizontalPadding * 2 + _CalloutSize.Width + (_Image != null ? _ImageSize.Width : 0)));
|
|
return textWidth;
|
|
}
|
|
|
|
public override void RecalcSize()
|
|
{
|
|
// We accept the width assigned and calculate the height based on that...
|
|
Rectangle bounds = this.DisplayRectangle;
|
|
Size imageSize = _ImageSize;
|
|
|
|
if (bounds.Width <= 0)
|
|
{
|
|
if (_Image != null)
|
|
bounds.Width = imageSize.Width;
|
|
bounds.Width += DefaultWidth;
|
|
}
|
|
|
|
if (_Image != null && bounds.Width - (imageSize.Width + 25) <= 1)
|
|
{
|
|
bounds.Height = imageSize.Height;
|
|
}
|
|
else
|
|
{
|
|
int totalHeight = VerticalPadding * 2;
|
|
Control parent = this.ContainerControl as Control;
|
|
if (parent != null)
|
|
{
|
|
Font font = parent.Font;
|
|
using (Graphics g = parent.CreateGraphics())
|
|
{
|
|
int textWidth = GetTextWidth(bounds);
|
|
Size textSize = TextDrawing.MeasureString(g, (string.IsNullOrEmpty(this.SourceName) ? "A" : this.SourceName), font);
|
|
totalHeight += textSize.Height + TextLineSpacing;
|
|
|
|
textSize = ButtonItemLayout.MeasureItemText(this, g, textWidth, font, eTextFormat.WordBreak, parent.RightToLeft == RightToLeft.Yes);
|
|
//textSize = TextDrawing.MeasureString(g, this.Text, font, textWidth, eTextFormat.WordBreak);
|
|
|
|
totalHeight += textSize.Height + TextLineSpacing;
|
|
}
|
|
}
|
|
bounds.Height = Math.Max(totalHeight, (imageSize != null ? imageSize.Height : MinimumHeight));
|
|
}
|
|
|
|
base.RecalcSize();
|
|
|
|
m_Rect = bounds;
|
|
}
|
|
|
|
public override void Paint(ItemPaintArgs p)
|
|
{
|
|
Graphics g = p.Graphics;
|
|
Rectangle bounds = this.DisplayRectangle;
|
|
|
|
if (_Image != null)
|
|
{
|
|
Rectangle imageRect = GetImageRect(bounds);
|
|
g.DrawImage(_Image, imageRect);
|
|
}
|
|
|
|
Rectangle contentBounds = GetContentBounds(bounds);
|
|
|
|
// Draw shadow
|
|
Rectangle shadowBounds = contentBounds;
|
|
shadowBounds.Inflate(1, 0);
|
|
shadowBounds.Offset(0, 1);
|
|
using (GraphicsPath path = CreateCalloutPath(shadowBounds))
|
|
{
|
|
using (Pen pen = new Pen(Color.FromArgb(32, Color.Black)))
|
|
g.DrawPath(pen, path);
|
|
}
|
|
|
|
using (GraphicsPath path = CreateCalloutPath(contentBounds))
|
|
{
|
|
Brush fill = GetCalloutBrush();
|
|
if (fill != null)
|
|
{
|
|
g.FillPath(fill, path);
|
|
fill.Dispose();
|
|
}
|
|
Pen pen = GetCalloutPen();
|
|
if (pen != null)
|
|
{
|
|
g.DrawPath(pen, path);
|
|
pen.Dispose();
|
|
}
|
|
}
|
|
|
|
Color headerColor = GetHeaderColor();
|
|
Rectangle headerTextBounds = GetTextBounds(bounds);
|
|
Rectangle textBounds = headerTextBounds;
|
|
string userName = this.SourceName;
|
|
if (!string.IsNullOrEmpty(userName))
|
|
{
|
|
using (Font font = new Font(p.Font, FontStyle.Bold))
|
|
{
|
|
TextDrawing.DrawString(g, userName, font, headerColor, headerTextBounds, eTextFormat.Top | eTextFormat.Left);
|
|
textBounds.Y += font.Height + TextLineSpacing;
|
|
textBounds.Height -= font.Height + TextLineSpacing;
|
|
}
|
|
}
|
|
if (_Created != DateTime.MinValue && _Created != DateTime.MaxValue)
|
|
{
|
|
TimeSpan span = DateTime.Now.Subtract(_Created);
|
|
//Console.WriteLine("Tweet from {0} created on {1}", SourceName, _Created);
|
|
string timeString = GetHumanTimeSpan(span);
|
|
using (Font font = new Font(p.Font, FontStyle.Italic))
|
|
{
|
|
TextDrawing.DrawString(g, timeString, font, headerColor, headerTextBounds, eTextFormat.Top | eTextFormat.Right);
|
|
headerTextBounds.Y += font.Height + TextLineSpacing;
|
|
headerTextBounds.Height -= font.Height + TextLineSpacing;
|
|
}
|
|
}
|
|
|
|
string text = this.Text;
|
|
Color textColor = GetTextColor();
|
|
if (!string.IsNullOrEmpty(text))
|
|
{
|
|
Font font = p.Font;
|
|
if (this.TextMarkupBody != null)
|
|
{
|
|
TextMarkup.MarkupDrawContext d = new TextMarkup.MarkupDrawContext(g, font, textColor, p.RightToLeft);
|
|
d.HotKeyPrefixVisible = true;
|
|
this.TextMarkupBody.Bounds = textBounds;
|
|
this.TextMarkupBody.Render(d);
|
|
}
|
|
else
|
|
TextDrawing.DrawString(g,
|
|
text,
|
|
font,
|
|
textColor,
|
|
textBounds,
|
|
eTextFormat.Top | eTextFormat.Left | eTextFormat.WordBreak | eTextFormat.WordEllipsis);
|
|
}
|
|
}
|
|
|
|
private Color _TextColor = Color.Empty;
|
|
/// <summary>
|
|
/// Gets or sets the color of the control text body.
|
|
/// </summary>
|
|
[Category("Columns"), Description("Indicates color of control text body.")]
|
|
public Color TextColor
|
|
{
|
|
get { return _TextColor; }
|
|
set { _TextColor = value; }
|
|
}
|
|
/// <summary>
|
|
/// Gets whether property should be serialized.
|
|
/// </summary>
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public bool ShouldSerializeTextColor()
|
|
{
|
|
return !_TextColor.IsEmpty;
|
|
}
|
|
/// <summary>
|
|
/// Resets property to its default value.
|
|
/// </summary>
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public void ResetTextColor()
|
|
{
|
|
this.TextColor = Color.Empty;
|
|
}
|
|
|
|
private Color GetTextColor()
|
|
{
|
|
if (!_TextColor.IsEmpty)
|
|
return _TextColor;
|
|
return Color.Black;
|
|
}
|
|
|
|
private Color _HeaderTextColor = Color.Empty;
|
|
/// <summary>
|
|
/// Gets or sets the color of the header text.
|
|
/// </summary>
|
|
[Category("Columns"), Description("Indicates color of header text.")]
|
|
public Color HeaderTextColor
|
|
{
|
|
get { return _HeaderTextColor; }
|
|
set { _HeaderTextColor = value; }
|
|
}
|
|
/// <summary>
|
|
/// Gets whether property should be serialized.
|
|
/// </summary>
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public bool ShouldSerializeHeaderTextColor()
|
|
{
|
|
return !_HeaderTextColor.IsEmpty;
|
|
}
|
|
/// <summary>
|
|
/// Resets property to its default value.
|
|
/// </summary>
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public void ResetHeaderTextColor()
|
|
{
|
|
this.HeaderTextColor = Color.Empty;
|
|
}
|
|
|
|
private Color GetHeaderColor()
|
|
{
|
|
if (!_HeaderTextColor.IsEmpty) return _HeaderTextColor;
|
|
return ColorScheme.GetColor(0x5D8CCB);
|
|
}
|
|
|
|
protected virtual Rectangle GetTextBounds(Rectangle bounds)
|
|
{
|
|
Rectangle textBounds = GetContentBounds(bounds);
|
|
if (_ImagePosition == eLogItemImagePosition.Left)
|
|
textBounds.X += _CalloutSize.Width;
|
|
textBounds.Width -= _CalloutSize.Width;
|
|
textBounds.Inflate(-HorizontalPadding, -VerticalPadding);
|
|
return textBounds;
|
|
}
|
|
|
|
private Brush GetCalloutBrush()
|
|
{
|
|
return new SolidBrush(_BackColor);
|
|
return new SolidBrush(ColorScheme.GetColor(0xE6EDF7));
|
|
return new SolidBrush(Color.FromArgb(208, Color.White));
|
|
}
|
|
|
|
private Pen GetCalloutPen()
|
|
{
|
|
return new Pen(ColorScheme.GetColor(0x5D8CC9), 1f);
|
|
}
|
|
|
|
private GraphicsPath CreateCalloutPath(Rectangle contentBounds)
|
|
{
|
|
GraphicsPath path = new GraphicsPath();
|
|
if (_ImagePosition == eLogItemImagePosition.Left)
|
|
{
|
|
if (_CornerSize == 0)
|
|
{
|
|
Rectangle pathBounds = contentBounds;
|
|
pathBounds.Width--;
|
|
pathBounds.Height--;
|
|
int i = _CalloutSize.Height / 2;
|
|
path.AddLine(pathBounds.X + _CalloutSize.Width, pathBounds.Y + _CalloutSize.Height + i, pathBounds.X, pathBounds.Y + i * 2);
|
|
path.AddLine(pathBounds.X, pathBounds.Y + i * 2, pathBounds.X + _CalloutSize.Width, pathBounds.Y + i);
|
|
path.AddLine(pathBounds.X + _CalloutSize.Width, pathBounds.Y, pathBounds.Right, pathBounds.Y);
|
|
path.AddLine(pathBounds.Right, pathBounds.Bottom, pathBounds.X + _CalloutSize.Width, pathBounds.Bottom);
|
|
path.CloseAllFigures();
|
|
}
|
|
else
|
|
{
|
|
Rectangle pathBounds = contentBounds;
|
|
pathBounds.Width--;
|
|
pathBounds.Height--;
|
|
int topOffset = _CornerSize;
|
|
int i = _CalloutSize.Height / 2;
|
|
path.AddLine(pathBounds.X + _CalloutSize.Width, pathBounds.Y + topOffset + _CalloutSize.Height + i, pathBounds.X, pathBounds.Y + topOffset + i * 2);
|
|
path.AddLine(pathBounds.X, pathBounds.Y + topOffset + i * 2, pathBounds.X + _CalloutSize.Width, pathBounds.Y + topOffset + i);
|
|
pathBounds.X += _CalloutSize.Width;
|
|
pathBounds.Width -= _CalloutSize.Width;
|
|
ArcData cornerArc = ElementStyleDisplay.GetCornerArc(pathBounds, _CornerSize, eCornerArc.TopLeft);
|
|
path.AddArc(cornerArc.X, cornerArc.Y, cornerArc.Width, cornerArc.Height, cornerArc.StartAngle, cornerArc.SweepAngle);
|
|
cornerArc = ElementStyleDisplay.GetCornerArc(pathBounds, _CornerSize, eCornerArc.TopRight);
|
|
path.AddArc(cornerArc.X, cornerArc.Y, cornerArc.Width, cornerArc.Height, cornerArc.StartAngle, cornerArc.SweepAngle);
|
|
cornerArc = ElementStyleDisplay.GetCornerArc(pathBounds, _CornerSize, eCornerArc.BottomRight);
|
|
path.AddArc(cornerArc.X, cornerArc.Y, cornerArc.Width, cornerArc.Height, cornerArc.StartAngle, cornerArc.SweepAngle);
|
|
cornerArc = ElementStyleDisplay.GetCornerArc(pathBounds, _CornerSize, eCornerArc.BottomLeft);
|
|
path.AddArc(cornerArc.X, cornerArc.Y, cornerArc.Width, cornerArc.Height, cornerArc.StartAngle, cornerArc.SweepAngle);
|
|
path.CloseAllFigures();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_CornerSize == 0)
|
|
{
|
|
Rectangle pathBounds = contentBounds;
|
|
pathBounds.Width--;
|
|
pathBounds.Height--;
|
|
int i = _CalloutSize.Height / 2;
|
|
path.AddLine(pathBounds.Right - _CalloutSize.Width, pathBounds.Y + _CalloutSize.Height + i, pathBounds.Right, pathBounds.Y + i * 2);
|
|
path.AddLine(pathBounds.Right, pathBounds.Y + i * 2, pathBounds.Right - _CalloutSize.Width, pathBounds.Y + i);
|
|
path.AddLine(pathBounds.Right - _CalloutSize.Width, pathBounds.Y, pathBounds.X, pathBounds.Y);
|
|
path.AddLine(pathBounds.X, pathBounds.Bottom, pathBounds.Right - _CalloutSize.Width, pathBounds.Bottom);
|
|
path.CloseAllFigures();
|
|
}
|
|
else
|
|
{
|
|
Rectangle pathBounds = contentBounds;
|
|
pathBounds.Width--;
|
|
pathBounds.Height--;
|
|
int topOffset = _CornerSize;
|
|
int i = _CalloutSize.Height / 2;
|
|
|
|
pathBounds.Width -= _CalloutSize.Width;
|
|
ArcData cornerArc = ElementStyleDisplay.GetCornerArc(pathBounds, _CornerSize, eCornerArc.TopLeft);
|
|
path.AddArc(cornerArc.X, cornerArc.Y, cornerArc.Width, cornerArc.Height, cornerArc.StartAngle, cornerArc.SweepAngle);
|
|
cornerArc = ElementStyleDisplay.GetCornerArc(pathBounds, _CornerSize, eCornerArc.TopRight);
|
|
path.AddArc(cornerArc.X, cornerArc.Y, cornerArc.Width, cornerArc.Height, cornerArc.StartAngle, cornerArc.SweepAngle);
|
|
|
|
pathBounds.Width += _CalloutSize.Width;
|
|
path.AddLine(pathBounds.Right - _CalloutSize.Width, pathBounds.Y + i, pathBounds.Right, pathBounds.Y + i * 2);
|
|
path.AddLine(pathBounds.Right, pathBounds.Y + i * 2, pathBounds.Right - _CalloutSize.Width, pathBounds.Y + _CalloutSize.Height + i);
|
|
pathBounds.Width -= _CalloutSize.Width;
|
|
|
|
cornerArc = ElementStyleDisplay.GetCornerArc(pathBounds, _CornerSize, eCornerArc.BottomRight);
|
|
path.AddArc(cornerArc.X, cornerArc.Y, cornerArc.Width, cornerArc.Height, cornerArc.StartAngle, cornerArc.SweepAngle);
|
|
cornerArc = ElementStyleDisplay.GetCornerArc(pathBounds, _CornerSize, eCornerArc.BottomLeft);
|
|
path.AddArc(cornerArc.X, cornerArc.Y, cornerArc.Width, cornerArc.Height, cornerArc.StartAngle, cornerArc.SweepAngle);
|
|
path.CloseAllFigures();
|
|
}
|
|
}
|
|
|
|
return path;
|
|
}
|
|
|
|
private Rectangle GetContentBounds(Rectangle bounds)
|
|
{
|
|
if (_Image != null)
|
|
{
|
|
if (_ImagePosition == eLogItemImagePosition.Left)
|
|
bounds.X += _ImageSize.Width;
|
|
bounds.Width -= _ImageSize.Width;
|
|
}
|
|
// Adjust for shadow
|
|
bounds.Height--;
|
|
bounds.Width--;
|
|
return bounds;
|
|
}
|
|
|
|
private Rectangle GetImageRect(Rectangle bounds)
|
|
{
|
|
if (_ImagePosition == eLogItemImagePosition.Left)
|
|
return new Rectangle(bounds.X, bounds.Y, _ImageSize.Width, _ImageSize.Height);
|
|
return new Rectangle(bounds.Right - _ImageSize.Width, bounds.Y, _ImageSize.Width, _ImageSize.Height);
|
|
}
|
|
|
|
private Image _Image = null;
|
|
private Size _ImageSize = new Size(48, 48);
|
|
/// <summary>
|
|
/// Gets or sets the image displayed on the log item.
|
|
/// </summary>
|
|
[DefaultValue(null), Category("Appearance"), Description("Specifies image displayed on the log item.")]
|
|
public Image Image
|
|
{
|
|
get { return _Image; }
|
|
set
|
|
{
|
|
if (_Image == value)
|
|
return;
|
|
_Image = value;
|
|
_ImageSize = new Size(48, 48);
|
|
if (_Image != null)
|
|
{
|
|
try
|
|
{
|
|
_ImageSize = _Image.Size;
|
|
}
|
|
catch { }
|
|
}
|
|
NeedRecalcSize = true;
|
|
this.Refresh();
|
|
}
|
|
}
|
|
|
|
private eLogItemImagePosition _ImagePosition = eLogItemImagePosition.Left;
|
|
/// <summary>
|
|
/// Gets or sets the image position in relation to text.
|
|
/// </summary>
|
|
[DefaultValue(eLogItemImagePosition.Left), Category("Appearance"), Description("Specifies the image position in relation to text.")]
|
|
public eLogItemImagePosition ImagePosition
|
|
{
|
|
get { return _ImagePosition; }
|
|
set
|
|
{
|
|
|
|
if (_ImagePosition == value)
|
|
return;
|
|
_ImagePosition = value;
|
|
NeedRecalcSize = true;
|
|
this.Refresh();
|
|
}
|
|
}
|
|
|
|
private string _SourceName = "";
|
|
[DefaultValue(""), Category("Appearance"), Description("Specifies the log item source name")]
|
|
public string SourceName
|
|
{
|
|
get { return _SourceName; }
|
|
set
|
|
{
|
|
_SourceName = value;
|
|
}
|
|
}
|
|
|
|
private DateTime _Created;
|
|
public DateTime Created
|
|
{
|
|
get { return _Created; }
|
|
set { _Created = value; }
|
|
}
|
|
|
|
private string GetHumanTimeSpan(TimeSpan span)
|
|
{
|
|
if (span.TotalMinutes <= 1.5)
|
|
return "now";
|
|
else if (span.TotalMinutes < 2)
|
|
return "about a minute ago";
|
|
else if (span.TotalMinutes < 60)
|
|
return span.TotalMinutes.ToString("N0") + " minutes ago";
|
|
else if (span.TotalHours < 2)
|
|
return span.TotalHours.ToString("N0") + " hour ago";
|
|
else if (span.TotalHours < 24)
|
|
return span.TotalHours.ToString("N0") + " hours ago";
|
|
else if (span.TotalDays < 2)
|
|
return span.TotalDays.ToString("N0") + " day ago";
|
|
else if (span.TotalDays < 30)
|
|
return span.TotalDays.ToString("N0") + " days ago";
|
|
return (span.TotalDays / 30).ToString("N0") + " months ago";
|
|
}
|
|
|
|
private Color _BackColor = Color.White;
|
|
/// <summary>
|
|
/// Gets or sets the background color of the item.
|
|
/// </summary>
|
|
[Category("Appearance"), Description("Indicates background color of the item.")]
|
|
public Color BackColor
|
|
{
|
|
get { return _BackColor; }
|
|
set
|
|
{
|
|
if (value != _BackColor)
|
|
{
|
|
Color oldValue = _BackColor;
|
|
_BackColor = value;
|
|
OnBackColorChanged(oldValue, value);
|
|
}
|
|
}
|
|
}
|
|
private void OnBackColorChanged(Color oldValue, Color newValue)
|
|
{
|
|
//OnPropertyChanged(new PropertyChangedEventArgs("BackColor"));
|
|
this.Refresh();
|
|
}
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public bool ShouldSerializeBackColor()
|
|
{
|
|
return _BackColor != Color.White;
|
|
}
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public void ResetBackColor()
|
|
{
|
|
this.BackColor = Color.White;
|
|
}
|
|
protected void SetBackColor(Color color)
|
|
{
|
|
_BackColor = color;
|
|
}
|
|
#endregion
|
|
|
|
#region Markup Support
|
|
/// <summary>
|
|
/// Gets whether item supports text markup. Default is false.
|
|
/// </summary>
|
|
protected override bool IsMarkupSupported
|
|
{
|
|
get { return true; }
|
|
}
|
|
|
|
protected override void TextMarkupLinkClick(object sender, EventArgs e)
|
|
{
|
|
TextMarkup.HyperLink link = sender as TextMarkup.HyperLink;
|
|
if (link != null)
|
|
OnMarkupLinkClick(new MarkupLinkClickEventArgs(link.Name, link.HRef));
|
|
base.TextMarkupLinkClick(sender, e);
|
|
}
|
|
|
|
protected virtual void OnMarkupLinkClick(MarkupLinkClickEventArgs e)
|
|
{
|
|
if (this.MarkupLinkClick != null)
|
|
MarkupLinkClick(this, e);
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
public enum eLogItemImagePosition
|
|
{
|
|
Left,
|
|
Right
|
|
}
|
|
}
|
|
#endif |