📄 expandablelist.cs
字号:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
namespace IssueVision
{
// ExpandableList is the generic implementation of the "Outlook" style list in the
// middle pane of IssueVision
public class ExpandableList : UserControl
{
// events
public delegate void DrawItemEventHandler(object sender, DrawItemEventArgs e, DataRowView dr);
public delegate void SelectionChangedEventHandler(DataRowView dr);
public delegate void SelectionDoubleClickedEventHandler(DataRowView dr);
public virtual event DrawItemEventHandler DrawItem;
public virtual event SelectionChangedEventHandler SelectionChanged;
public virtual event SelectionDoubleClickedEventHandler SelectionDoubleClicked;
// internal members
private DataView m_dataSource;
private GroupItemCollection m_groupList = new GroupItemCollection();
private int m_itemHeight = SectionControl.DefaultItemHeight;
private IContainer components = null;
[DefaultValueAttribute(typeof(DataView), null)]
[CategoryAttribute("Data")]
public DataView DataSource
{
get
{
return m_dataSource;
}
set
{
m_dataSource = value;
}
}
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)]
[CategoryAttribute("Data")]
public GroupItemCollection GroupList
{
get
{
return m_groupList;
}
}
[DefaultValueAttribute(SectionControl.DefaultItemHeight)]
[CategoryAttribute("Layout")]
public int ItemHeight
{
get
{
return m_itemHeight;
}
set
{
m_itemHeight = value;
}
}
public ExpandableList()
{
InitializeComponent();
SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer, true);
}
public void LayoutSections()
{
SuspendLayout();
while (Controls.Count > 0)
{
RemoveDrawItemHandler(Controls[0]);
Controls.RemoveAt(0);
}
ArrayList al = new ArrayList();
if (m_groupList != null)
{
foreach (GroupItem gi in m_groupList)
{
Splitter sp = new Splitter();
sp.BackColor = SystemColors.Window;
sp.Dock = DockStyle.Top;
sp.Enabled = false;
sp.Height = 2;
al.Add(sp);
SectionControl sc = new SectionControl();
sc.DataSource = m_dataSource.FindRows(gi.RowFilter);
sc.Dock = DockStyle.Top;
sc.Text = gi.GroupTitle;
sc.DrawItem += new SectionControl.DrawItemEventHandler(this.SectionControl_DrawItem);
sc.SelectionChanged += new SectionControl.SelectionChangedEventHandler(this.SectionControl_SelectionChanged);
sc.SelectionDoubleClicked += new SectionControl.SelectionDoubleClickedEventHandler(this.SectionControl_SelectionDoubleClicked);
al.Add(sc);
}
//Add the controls in reverse order for proper layout.
for (int i = al.Count - 1; i >= 0; i--)
{
Controls.Add((Control)al[i]);
}
}
ResumeLayout();
// TODO: The vertical scrollbar is not always shown after
// the list is repopulated with controls. Setting the
// AutoScroll property forces the control to display the
// scrollbar if necessary, but is a work around.
// The problem occurs when list is populated with controls
// that don't require a scrollbar, and then populated
// with controls that do require a scrollbar, but the
// scrollbar is not visible until you collapse and
// expand an item.
AutoScroll = true;
}
private void RemoveDrawItemHandler(Control c)
{
try
{
SectionControl sc = c as SectionControl;
if (sc != null)
{
sc.DrawItem -= new SectionControl.DrawItemEventHandler(this.SectionControl_DrawItem);
sc.SelectionChanged -= new SectionControl.SelectionChangedEventHandler(this.SectionControl_SelectionChanged);
}
}
catch
{
// Eat this exception. We attempt to cast every control to type SectionControl,
// and most will fail.
}
}
protected virtual void OnDrawItem(DrawItemEventArgs e, DataRowView dr)
{
if (DrawItem != null)
{
DrawItem(this, e, dr);
}
}
protected virtual void OnSelectionChanged(DataRowView dr)
{
if (SelectionChanged != null)
{
SelectionChanged(dr);
}
}
private void ExpandableList_Load(object sender, EventArgs e)
{
LayoutSections();
}
private void SectionControl_DrawItem(object sender, DrawItemEventArgs e, DataRowView dr)
{
OnDrawItem(e, dr);
}
private void SectionControl_SelectionDoubleClicked(SectionControl sender, DataRowView dr)
{
if (SelectionDoubleClicked != null)
{
SelectionDoubleClicked(null);
}
}
private void SectionControl_SelectionChanged(SectionControl sender, DataRowView dr)
{
// The selection changed in one of the section controls.
// Make sure any previous selection in another section
// control is cleared.
foreach (Control c in this.Controls)
{
if (c is SectionControl)
{
SectionControl sc = (SectionControl)c;
if (sc != sender)
{
//clear selected row
sc.SelectedIndex = -1;
}
}
}
// raise selection event
OnSelectionChanged(dr);
}
// select the row that contains the specified data row,
// raiseChangedEvent specifies if the selection changed event should
// be raised if a row is selected
public bool SelectRow(DataRowView dr, bool raiseChangedEvent)
{
// loop through the controls and find the row that
// contains the data row
foreach (Control c in this.Controls)
{
if (c is SectionControl)
{
SectionControl sc = (SectionControl)c;
int index = sc.GetRow(dr);
if (index != -1)
{
// found the row, tell that section group to
// select the row and raise the event if specified
sc.SelectedIndex = index;
if (raiseChangedEvent)
{
OnSelectionChanged(sc.DataSource[index]);
}
return true;
}
}
}
//did not find a row that contains the data
return false;
}
// select the first row in the first section group,
// raiseChangedEvent specifies if the selection changed event should be raised
public bool SelectFirstRow(bool raiseChangedEvent)
{
// controls are in reverse order
for (int i = Controls.Count - 1; i >= 0; i--)
{
if (Controls[i] is SectionControl)
{
// select the first row in this section group, if it contains any rows
SectionControl sc = (SectionControl)Controls[i];
if (sc.Count > 0)
{
sc.SelectedIndex = 0;
if (raiseChangedEvent)
{
OnSelectionChanged(sc.DataSource[0]);
}
return true;
}
}
}
// there are not any rows to select
return false;
}
// indicate that an empty row is selected
// raiseChangedEvent specifies if the selection changed event should be raised
public void SelectEmptyRow(bool raiseChangedEvent)
{
OnSelectionChanged(null);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
foreach (Control c in this.Controls)
{
RemoveDrawItemHandler(c);
}
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
[DebuggerStepThroughAttribute()]
private void InitializeComponent()
{
AutoScroll = true;
base.Load += new EventHandler(this.ExpandableList_Load);
Name = "ExpandableList";
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -