using System;
using System.Collections.Generic;
namespace SecretNest.RecursiveEnumerator
{
/// <summary>
/// Get the enumerator for querying the parents of specified item.
/// </summary>
/// <typeparam name="T">Item type</typeparam>
/// <param name="current">Item for querying parents</param>
/// <returns>Enumerator of parents querying</returns>
public delegate IEnumerator<T> GetParentsEnumerator<T>(T current);
/// <summary>
/// Enumerator for querying parents
/// </summary>
/// <typeparam name="T">Item type</typeparam>
public class Enumerator<T> : IEnumerator<T>
{
T current, initial;
Queue<T> notQueried = new Queue<T>();
HashSet<T> queried = new HashSet<T>(); //for avoiding duplicated query
Queue<T> rollbackHistory = new Queue<T>(); //for soft reset
Queue<T> history = new Queue<T>(); //for soft reset
IEnumerator<T> activeQuery;
/// <summary>
/// Callback for getting the enumerator, which is used for querying the parents of specified item.
/// </summary>
public GetParentsEnumerator<T> GetParentsEnumeratorCallback { get; set; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="initial">Initial item</param>
public Enumerator(T initial)
{
notQueried.Enqueue(initial);
this.initial = initial;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="initial">Initial item</param>
/// <param name="callback">Callback for getting the enumerator, which is used for querying the parents of specified item.</param>
public Enumerator(T initial, GetParentsEnumerator<T> callback)
{
notQueried.Enqueue(initial);
this.initial = initial;
GetParentsEnumeratorCallback = callback;
}
/// <summary>
/// Gets the current element in the collection.
/// </summary>
public T Current
{
get { return current; }
}
bool disposed;
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
current = default(T);
notQueried = null;
queried = null;
history = null;
}
disposed = true;
}
}
/// <summary>
/// Gets the current element in the collection.
/// </summary>
object System.Collections.IEnumerator.Current
{
get { return current; }
}
/// <summary>
/// Skip same items
/// </summary>
public bool SkipSameItems { get; set; }
/// <summary>
/// Advances the enumerator to the next element of the collection.
/// </summary>
/// <returns>true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection. </returns>
public bool MoveNext()
{
if (disposed) throw new ObjectDisposedException(null);
if (rollbackHistory.Count > 0)
{
current = rollbackHistory.Dequeue();
history.Enqueue(current);
return true;
}
if (activeQuery != null)
{
here:
if (activeQuery.MoveNext())
{
if (SkipSameItems && history.Contains(activeQuery.Current)) { goto here; }
current = activeQuery.Current;
history.Enqueue(current);
notQueried.Enqueue(current);
return true;
}
else
{
activeQuery = null;
}
}
if (GetParentsEnumeratorCallback != null)
{
while (notQueried.Count != 0)
{
T item = notQueried.Dequeue();
if (!queried.Contains(item))
{
IEnumerator<T> enumerator = GetParentsEnumeratorCallback(item);
queried.Add(item);
here:
if (enumerator != null)
{
if (enumerator.MoveNext())
{
activeQuery = enumerator;
if (SkipSameItems && history.Contains(enumerator.Current)) { goto here; }
current = enumerator.Current;
history.Enqueue(current);
notQueried.Enqueue(current);
return true;
}
else
{
enumerator = null;
}
}
}
}
}
return false;
}
/// <summary>
/// Sets the enumerator to its initial position, which is before the first element in the collection. Keep all histories for caching.
/// </summary>
public void Reset()
{
if (disposed) throw new ObjectDisposedException(null);
while (history.Count > 0)
{
rollbackHistory.Enqueue(history.Dequeue());
}
current = default(T);
}
/// <summary>
/// Sets the enumerator to its initial position, which is before the first element in the collection. Reset all data, and close active sub-query.
/// </summary>
public void HardReset()
{
if (disposed) throw new ObjectDisposedException(null);
queried.Clear();
notQueried.Clear();
notQueried.Enqueue(initial);
history.Clear();
activeQuery = null;
current = default(T);
}
}
}
Category: dotNet Product
Chorus Update: Invoke Helper
A new Invoke Helper is added for making it easier with creating subscribers for UI updating job, by calling Invoke method internally.
See Chorus page for more information.
TreeView with CheckBox
If you wanna use CheckBox enabled TreeView in Windows Vista and further systems, you need to pay attention. If you double click the CheckBoxes in the TreeView, some useful event handlers, like BeforeClick and AfterClick, will not be raised. And, the vision of CheckBoxes will be changed (checked or not) but the property of related TreeNode will not.
To fix this, you have to create your own TreeView instead of the provided one.
using System;
using System.Windows.Forms;
[
ComVisible(true),
ClassInterface(ClassInterfaceType.AutoDispatch),
DefaultProperty("Nodes"),
DefaultEvent("AfterSelect"),
Docking(DockingBehavior.Ask),
Designer("System.Windows.Forms.Design.TreeViewDesigner"),
]
public class FixedTreeView : TreeView
{
protected override void WndProc(ref Message m)
{
// Suppress WM_LBUTTONDBLCLK
if (m.Msg == 0x203)
{
m.Result = IntPtr.Zero;
}
else
{
base.WndProc(ref m);
}
}
}
Source: http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/9d717ce0-ec6b-4758-a357-6bb55591f956
Chorus Update
Performance optimized. Chorus will require little more memory but run much faster.
Document(pdf) error fixed.
No interface / flow changed. You don’t need to adjust your code. Just download the new version and enjoy it.
Chorus本地模式版已经发布
Chorus是一个框架,它实现了多个部件之间的通讯功能。在它的协助下,软件系统中的每个部件可以自由通讯,而不论这些部件运行在同一个程序,同一台计算机,还是在世界的任何角落。
Chorus是一种模型,它展示了软件系统内部的物理结构。在它的支持下,软件系统中的每个部件可以随心拼装,而不论这些部件构造于您的产品,您的企业,还是获取自其他供应商。
Chorus是一份标准,它定义了每个程序部件的接口规格。在它的规范下,软件系统中的每个部件可以严格定义,而不论这些部件开发于同一个员工,同一个小组,还是来自外包公司。
当前已经发布本地模式版,实现同一个应用程序内部的通讯功能。
您有兴趣了解吗?请访问Chorus发布页。
Multi-Column ComboBox
a dotNet user control
Framework version: 3.5
Download dll with demo written in VB.Net.
Source code written in VB.Net.
Software and code is provided with MIT license.
网络调试用工具包
注:以下软件均为较久前开发,需要dotNet Framework 1.1框架,不能兼容最新框架。
Redirector:TCP/UDP端口转发工具。
Smiler:TCP/UDP调试工具,支持作为客户端、服务器,并有多种编码支持。
UDPSimulator:UDP网络环境模拟器,通过对UDP包的转发,模拟网络上可能出现的丢包和顺序错位。