using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Drawing;
using System.Diagnostics;
using System.Reflection;
using Sheng.Winform.Controls.Kernal;
using System.Collections;
namespace Sheng.Winform.Controls
{
///
///
///
public class ShengListView : Control
{
#region 常量
///
/// Creates a control with a border.
///
private const int WS_BORDER = 0x00800000;
///
/// Specifies that the control has a border with a sunken edge.
///
private const int WS_EX_CLIENTEDGE = 0x00000200;
#endregion
#region 私有成员
private bool _suspendLayout = false;
///
///
///
public bool Suspend
{
get { return _suspendLayout; }
}
///
/// 是否需要在调用 ResumeLayout 时重绘
///
private bool _needPaint = false;
private ShengListViewLayoutManager _layoutManager;
///
/// 为项扩展的用于呈现的属性
///
private readonly Dictionary _extendMember = new Dictionary();
//ToolTip _toolTip = new ToolTip();
//private System.Timers.Timer lazyRefreshTimer;
#endregion
#region 公开属性
///
/// Gets whether the shift key is down.
///
internal bool ShiftKey { get; private set; }
///
/// Gets whether the control key is down.
///
internal bool ControlKey { get; private set; }
///
/// 鼠标左键是否处于按下状态
///
internal bool LeftButton { get; private set; }
///
/// 鼠标右键是否处于按下状态
///
internal bool RightButton { get; private set; }
internal bool AnyMouseButton
{
get { return LeftButton || RightButton; }
}
//debug public
///
/// 鼠标最后点击的位置
///
internal Point LastMouseDownLocation { get; private set; }
private ShengListViewItem _hoveredItem;
///
/// 当前鼠标经过的项
///
internal ShengListViewItem HoveredItem
{
get { return _hoveredItem; }
private set
{
ShengListViewItem oldHoveredItem = _hoveredItem;
ShengListViewItem newHoveredItem = value;
_hoveredItem = value;
if (oldHoveredItem != null && oldHoveredItem != newHoveredItem)
{
oldHoveredItem.Hovered = false;
}
if (newHoveredItem != null)
newHoveredItem.Hovered = true;
if (oldHoveredItem != newHoveredItem)
{
NeedPaint();
}
}
}
private ShengListViewLayoutMode _layoutMode;
///
///
///
public ShengListViewLayoutMode LayoutMode
{
get { return _layoutMode; }
set
{
_layoutMode = value;
ShengListViewLayoutManager layoutManager;
switch (_layoutMode)
{
case ShengListViewLayoutMode.Standard:
layoutManager = new ShengListViewStandardLayoutManager(this);
break;
case ShengListViewLayoutMode.Descriptive:
layoutManager = new ShengListViewDescriptiveLayoutManager(this);
break;
default:
layoutManager = new ShengListViewLayoutManager(this);
Debug.Assert(false, "没这ListViewRenderer");
break;
}
SetLayoutManager(layoutManager);
}
}
private BorderStyle _borderStyle = BorderStyle.Fixed3D;
///
///
///
public BorderStyle BorderStyle
{
get { return _borderStyle; }
set { _borderStyle = value; }
}
private ShengListViewTheme _theme = new ShengListViewTheme();
///
/// 配色方案
///
public ShengListViewTheme Theme
{
get
{
return _theme;
}
set
{
_theme = value;
Refresh();
}
}
///
/// 当前布局中项的高度
///
public int ItemHeight
{
get { return _layoutManager.ItemHeightWithMargin; }
}
private bool _allowMultiSelection = false;
///
///
///
public bool AllowMultiSelection
{
get { return _allowMultiSelection; }
set { _allowMultiSelection = value; }
}
///
/// 是否没有任何项
///
public bool IsEmpty
{
get
{
return Items.Count == 0;
}
}
private ShengListViewItemCollection _items = new ShengListViewItemCollection();
///
///
///
public ShengListViewItemCollection Items
{
get { return _items; }
set { _items = value; }
}
///
/// 获取当前具有输入焦点的项
///
public ShengListViewItem FocusedItem
{
get
{
foreach (var item in _items)
{
if (item.Focused)
return item;
}
return null;
}
}
///
/// 默认的用于呈现为项中文本的Property
///
public string DisplayMember
{
get;
set;
}
#endregion
#region 构造
///
///
///
public ShengListView()
{
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.Selectable, true);
this.Padding = new System.Windows.Forms.Padding(10);
_items.Owner = this;
//设置一个默认布局
this.LayoutMode = ShengListViewLayoutMode.Standard;
//_layoutManager = new ListViewLayoutManager(this);
//lazyRefreshTimer = new System.Timers.Timer();
//lazyRefreshTimer.Interval = 10;
//lazyRefreshTimer.Enabled = false;
//lazyRefreshTimer.Elapsed += lazyRefreshTimer_Tick;
//lazyRefreshCallback = new RefreshDelegateInternal(Refresh);
}
//delegate void RefreshDelegateInternal();
//private RefreshDelegateInternal lazyRefreshCallback;
//void lazyRefreshTimer_Tick(object sender, EventArgs e)
//{
// if (IsHandleCreated && IsDisposed == false)
// BeginInvoke(lazyRefreshCallback);
// lazyRefreshTimer.Stop();
//}
#endregion
#region 方法
#region internal
///
/// 更改了选择的项
///
internal void OnSelectedItemChanged()
{
SelectedItemChanaged?.Invoke(this, new EventArgs());
}
///
/// 双击项
///
///
internal void OnItemDoubleClick(ShengListViewItem item)
{
ItemDoubleClick?.Invoke(this, new ShengListViewItemDoubleClickEventArgs(item));
}
internal void OnItemsRemoved(List items)
{
_layoutManager.OnItemsRemoved(items);
ItemsRemoved?.Invoke(this, new ShengListViewItemsRemovedEventArgs(items));
}
///
/// 请求在下次调用 ResumeLayout 时重绘
///
internal void NeedPaint()
{
_needPaint = true;
}
internal void RenderItem(ShengListViewItem item)
{
if (Suspend == false)
{
_layoutManager.RenderItem(this.CreateGraphics(), item);
}
}
internal object GetItemPropertyValue(object itemValue, string propertyName)
{
if (itemValue == null || String.IsNullOrEmpty(propertyName))
{
Debug.Assert(false, "itemValue 或 propertyName 为空");
throw new ArgumentNullException();
}
return ReflectionPool.GetPropertyValue(itemValue, propertyName);
}
internal string GetItemText(object itemValue)
{
Debug.Assert(itemValue != null, "itemValue 为 null");
if (itemValue == null)
return String.Empty;
if (ItemTextGetting != null)
{
ShengListViewGetItemTextEventArgs args = new ShengListViewGetItemTextEventArgs(itemValue);
ItemTextGetting(this, args);
if (String.IsNullOrEmpty(args.Text) == false)
return args.Text;
}
if (String.IsNullOrEmpty(DisplayMember))
{
return itemValue.ToString();
}
else
{
return GetItemText(itemValue, DisplayMember);
}
}
internal string GetItemText(object itemValue, string propertyName)
{
Debug.Assert(itemValue != null && String.IsNullOrEmpty(propertyName) == false, "itemValue 为 null");
object text = GetItemPropertyValue(itemValue, propertyName);
if (text == null)
return String.Empty;
else
return text.ToString();
}
///
/// 获取当前选中的所有项
///
///
internal List GetSelectedItems()
{
List items = new List();
foreach (var item in _items)
{
if (item.Selected)
items.Add(item);
}
return items;
}
#endregion
#region public
///
///
///
///
public void AddExtendMember(IShengListViewExtendMember member)
{
Dictionary extendMembers = member.GetExtendMembers();
foreach (var item in extendMembers)
{
SetExtendMember(item.Key, item.Value);
}
}
///
/// 设置扩展属性供特定LayoutEngine使用
/// 如果指定的 ExtendMember 已存在,覆盖之
/// 用String.Empty 或 null 做为 propertyName传入,表示删除指定的 member
///
///
///
public void SetExtendMember(string member, string propertyName)
{
if (String.IsNullOrEmpty(member))
{
Debug.Assert(false, "member 为空");
throw new ArgumentNullException();
}
if (String.IsNullOrEmpty(propertyName))
{
_extendMember.Remove(member);
}
else
{
if (_extendMember.Keys.Contains(member))
{
_extendMember[member] = propertyName;
}
else
{
_extendMember.Add(member, propertyName);
}
}
}
///
///
///
///
///
public bool ContainerExtendMember(string member)
{
if (String.IsNullOrEmpty(member) )
{
Debug.Assert(false, "member 为空");
throw new ArgumentNullException();
}
return _extendMember.Keys.Contains(member);
}
///
///
///
///
///
public string GetExtendMember(string member)
{
if (ContainerExtendMember(member) == false)
{
Debug.Assert(false, "指定的 member 不存在" + member);
throw new ArgumentOutOfRangeException();
}
return _extendMember[member];
}
///
/// 恢复正常的布局逻辑。
///
public new void ResumeLayout()
{
_suspendLayout = false;
if (_needPaint)
{
this.Refresh();
_needPaint = false;
}
base.ResumeLayout();
}
///
///
///
///
public new void ResumeLayout(bool refreshNow)
{
_suspendLayout = false;
if (refreshNow)
{
this.Refresh();
_needPaint = false;
}
else
{
ResumeLayout();
}
base.ResumeLayout(refreshNow);
}
///
/// 临时挂起控件的布局逻辑。
///
public new void SuspendLayout()
{
_suspendLayout = true;
base.SuspendLayout();
}
///
///
///
public override void Refresh()
{
if (_suspendLayout)
return;
base.Refresh();
}
///
/// 获取当前选中项所绑定的对象
/// 如果没有选中项,返回null,如果选中多项,返回选中项集合中的第一个
///
///
public object GetSelectedValue()
{
List selectedItems = GetSelectedItems();
if (selectedItems.Count == 0)
return null;
return selectedItems[0].Value;
}
///
/// 根据指定的绑定项对象
/// 设置当前列表中选定的项
///
///
public void SetSelectedValue(object obj)
{
if (obj == null)
{
ClearSelect();
return;
}
var items = (from item in _items where item.Value == obj select item).ToList();
if (items.Count == 0)
{
Debug.Assert(false, "没有指定的项");
return;
}
var oldSelectedItems = GetSelectedItems();
//这里为什么用foreach
//考虑到多个项绑定到同一个对象的情况,不过理论上讲不应该出现这种情况
SuspendLayout();
ClearSelect();
foreach (var item in items)
{
item.Selected = true;
}
ResumeLayout();
if (items.SequenceEqual(oldSelectedItems) == false)
OnSelectedItemChanged();
}
///
/// 获取当前选中的所有项的绑定对象集合
/// 如果当前没有选中任何项,返回空集合
///
///
public List