📄 virtualobjectlistview.cs
字号:
/// </para>
/// </remarks>
protected override void HandleColumnClick(object sender, ColumnClickEventArgs e)
{
if (!this.PossibleFinishCellEditing())
return;
// Toggle the sorting direction on successive clicks on the same column
SortOrder order = SortOrder.Ascending;
if (this.LastSortColumn != null && e.Column == this.LastSortColumn.Index)
order = (this.LastSortOrder == SortOrder.Descending ? SortOrder.Ascending : SortOrder.Descending);
this.BeginUpdate();
try {
this.Sort(this.GetColumn(e.Column), order);
}
finally {
this.EndUpdate();
}
}
/// <summary>
/// Handle a RetrieveVirtualItem
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void HandleRetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
// .NET 2.0 seems to generate a lot of these events. Before drawing *each* sub-item,
// this event is triggered 4-8 times for the same index. So we save lots of CPU time
// by caching the last result.
if (this.lastRetrieveVirtualItemIndex != e.ItemIndex) {
this.lastRetrieveVirtualItemIndex = e.ItemIndex;
this.lastRetrieveVirtualItem = this.MakeListViewItem(e.ItemIndex);
}
e.Item = this.lastRetrieveVirtualItem;
}
/// <summary>
/// Handle the SearchForVirtualList event, which is called when the user types into a virtual list
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void HandleSearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e)
{
// The event has e.IsPrefixSearch, but as far as I can tell, this is always false (maybe that's different under Vista)
// So we ignore IsPrefixSearch and IsTextSearch and always to a case insensitve prefix match.
// We can't do anything if we don't have a data source
if (this.DataSource == null)
return;
// Where should we start searching? If the last row is focused, the SearchForVirtualItemEvent starts searching
// from the next row, which is actually an invalidate index -- so we make sure we never go past the last object.
int start = Math.Min(e.StartIndex, this.DataSource.GetObjectCount() - 1);
// Give the world a chance to fiddle with or completely avoid the searching process
BeforeSearchingEventArgs args = new BeforeSearchingEventArgs(e.Text, start);
this.OnBeforeSearching(args);
if (args.Canceled)
return;
// Do the search
int i = this.FindMatchingRow(args.StringToFind, args.StartSearchFrom, e.Direction);
// Tell the world that a search has occurred
AfterSearchingEventArgs args2 = new AfterSearchingEventArgs(args.StringToFind, i);
this.OnAfterSearching(args2);
// If we found a match, tell the event
if (i != -1)
e.Index = i;
}
/// <summary>
/// Find the first row in the given range of rows that prefix matches the string value of the given column.
/// </summary>
/// <param name="text"></param>
/// <param name="first"></param>
/// <param name="last"></param>
/// <param name="column"></param>
/// <returns>The index of the matched row, or -1</returns>
protected override int FindMatchInRange(string text, int first, int last, OLVColumn column)
{
return this.DataSource.SearchText(text, first, last, column);
}
#endregion
#region Variable declaractions
private Dictionary<Object, CheckState> checkStateMap = new Dictionary<object, CheckState>();
private OLVListItem lastRetrieveVirtualItem;
private int lastRetrieveVirtualItemIndex = -1;
#endregion
}
/// <summary>
/// A VirtualListDataSource is a complete manner to provide functionality to a virtual list.
/// An object that implements this interface provides a VirtualObjectListView with all the
/// information it needs to be fully functional.
/// </summary>
/// <remarks>Implementors must provide functioning implementations of GetObjectCount()
/// and GetNthObject(), otherwise nothing will appear in the list.</remarks>
public interface IVirtualListDataSource
{
/// <summary>
/// Return the object that should be displayed at the n'th row.
/// </summary>
/// <param name="n">The index of the row whose object is to be returned.</param>
/// <returns>The model object at the n'th row, or null if the fetching was unsuccessful.</returns>
Object GetNthObject(int n);
/// <summary>
/// Return the number of rows that should be visible in the virtual list
/// </summary>
/// <returns>The number of rows the list view should have.</returns>
int GetObjectCount();
/// <summary>
/// Get the index of the row that is showing the given model object
/// </summary>
/// <param name="model">The model object sought</param>
/// <returns>The index of the row showing the model, or -1 if the object could not be found.</returns>
int GetObjectIndex(Object model);
/// <summary>
/// The ListView is about to request the given range of items. Do
/// whatever caching seems appropriate.
/// </summary>
/// <param name="first"></param>
/// <param name="last"></param>
void PrepareCache(int first, int last);
/// <summary>
/// Find the first row that "matches" the given text in the given range.
/// </summary>
/// <param name="value">The text typed by the user</param>
/// <param name="first">Start searching from this index. This may be greater than the 'to' parameter,
/// in which case the search should descend</param>
/// <param name="last">Do not search beyond this index. This may be less than the 'from' parameter.</param>
/// <param name="column">The column that should be considered when looking for a match.</param>
/// <returns>Return the index of row that was matched, or -1 if no match was found</returns>
int SearchText(string value, int first, int last, OLVColumn column);
/// <summary>
/// Sort the model objects in the data source.
/// </summary>
/// <param name="column"></param>
/// <param name="order"></param>
void Sort(OLVColumn column, SortOrder order);
//-----------------------------------------------------------------------------------
// Modification commands
// THINK: Should we split these three into a separate interface?
/// <summary>
/// Add the given collection of model objects to this control.
/// </summary>
/// <param name="modelObjects">A collection of model objects</param>
void AddObjects(ICollection modelObjects);
/// <summary>
/// Remove all of the given objects from the control
/// </summary>
/// <param name="modelObjects">Collection of objects to be removed</param>
void RemoveObjects(ICollection modelObjects);
/// <summary>
/// Set the collection of objects that this control will show.
/// </summary>
/// <param name="collection"></param>
void SetObjects(IEnumerable collection);
}
/// <summary>
/// A do-nothing implementation of the VirtualListDataSource interface.
/// </summary>
public class AbstractVirtualListDataSource : IVirtualListDataSource
{
public AbstractVirtualListDataSource(VirtualObjectListView listView)
{
this.listView = listView;
}
/// <summary>
/// The list view that this data source is giving information to.
/// </summary>
protected VirtualObjectListView listView;
public virtual object GetNthObject(int n)
{
return null;
}
public virtual int GetObjectCount()
{
return -1;
}
public virtual int GetObjectIndex(object model)
{
return -1;
}
public virtual void PrepareCache(int from, int to)
{
}
public virtual int SearchText(string value, int first, int last, OLVColumn column)
{
return -1;
}
public virtual void Sort(OLVColumn column, SortOrder order)
{
}
public virtual void AddObjects(ICollection modelObjects)
{
}
public virtual void RemoveObjects(ICollection modelObjects)
{
}
public virtual void SetObjects(IEnumerable collection)
{
}
/// <summary>
/// This is a useful default implementation of SearchText method, intended to be called
/// by implementors of IVirtualListDataSource.
/// </summary>
/// <param name="value"></param>
/// <param name="first"></param>
/// <param name="last"></param>
/// <param name="column"></param>
/// <param name="source"></param>
/// <returns></returns>
static public int DefaultSearchText(string value, int first, int last, OLVColumn column, IVirtualListDataSource source)
{
if (first <= last) {
for (int i = first; i <= last; i++) {
string data = column.GetStringValue(source.GetNthObject(i));
if (data.StartsWith(value, StringComparison.CurrentCultureIgnoreCase))
return i;
}
} else {
for (int i = first; i >= last; i--) {
string data = column.GetStringValue(source.GetNthObject(i));
if (data.StartsWith(value, StringComparison.CurrentCultureIgnoreCase))
return i;
}
}
return -1;
}
}
/// <summary>
/// This class mimics the behavior of VirtualObjectListView v1.x.
/// </summary>
public class VirtualListVersion1DataSource : AbstractVirtualListDataSource
{
public VirtualListVersion1DataSource(VirtualObjectListView listView) : base (listView)
{
}
#region Public properties
/// <summary>
/// How will the n'th object of the data source be fetched?
/// </summary>
public RowGetterDelegate RowGetter
{
get { return rowGetter; }
set { rowGetter = value; }
}
private RowGetterDelegate rowGetter;
#endregion
#region IVirtualListDataSource implementation
public override object GetNthObject(int n)
{
if (this.RowGetter == null)
return null;
else
return this.RowGetter(n);
}
public override int SearchText(string value, int first, int last, OLVColumn column)
{
return DefaultSearchText(value, first, last, column, this);
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -