C#中是否有办法检查对象是否挂起?我有一个TreeView,我需要知道它是否仍然挂起。
myTreeView.BeginUpdate();
myTreeView.SuspendLayout();
// Do Stuff.
myTreeView.EndUpdate();
myTreeView.ResumeLayout();
因为我在递归函数中有这个代码,所以我想知道TreeView是否已被暂停。
答案 0 :(得分:11)
根据verminity的回答你有一个选择:
使用以下课程
public class SuspendAwareTreeView : TreeView
{
public readonly T RealControl;
private int suspendCount;
public bool IsSuspended
{
get { return suspendCount > 0; }
}
public Suspendable(T real) { this.RealControl = real; }
public void SuspendLayout()
{
this.suspendCount++;
this.RealControl.SuspendLayout();
}
public void ResumeLayout()
{
this.RealControl.ResumeLayout();
this.suspendCount--;
}
}
然后在您需要暂停它的内部使用此类。
显然,如果您将类传递给只需要控件或者控制之外的其他东西设置它,那么这将无效。
如果是这种情况,您将被迫使用各种不太令人满意的解决方案:
根据您的需要当且仅当您控制完全运行的运行时版本(即受控企业环境)时,以下邪恶但有效的黑客是合适的。只要您在升级时进行测试,它就可以轻松地继续工作。
public class ControlInvader
{
private static readonly System.Reflection.FieldInfo layoutSuspendCount =
typeof(Control).GetField("layoutSuspendCount",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic);
private readonly Control control;
public bool IsSuspended
{
get
{
return 0 != (byte)layoutSuspendCount.GetValue(this.control);
}
}
public Suspendable(Control control) { this.control = control; }
}
将其附加到TreeView,然后您可以随时检查该值。
重申这是脆弱的,并且完全不适用于未严格控制底层运行时版本的环境,以及您可以在可能的重大努力上解决这一问题。 你最好包括一个静态初始化程序,它检查字段是否实际存在且是正确的类型,如果没有则中止。
答案 1 :(得分:9)
嗯,这是一种迟到的答案,但在内部,控件正在跟踪计数,并且只会在大多数简历声明中恢复。那你为什么一开始就关心它,你只需确保你调用暂停并在finally块中恢复它:
void Recursive(Control c)
{
c.SuspendLayout();
try
{
if (existCondition) return;
// do stuff
Recursive(c);
}
finally
{
c.ResumeLayout(true);
}
}
这是有效的,因为以下是控制内部如何按以下顺序对您的通话作出反应:
c.SuspendLayout() // 1st call suspends layout
c.SuspendLayout() // 2nd and subsequent call only increase the count and does nothing.
....
c.ResumeLayout(true) // this decrease the count to 1 and does NOT actually resumes layout.
c.ResumeLayout(true) // this set the count to 0 and REALLY resumes layout.
HTH
答案 2 :(得分:3)
在System.Windows.Forms.Control的SuspendLayout方法中快速查看Reflector,显示以下内容:
public void SuspendLayout()
{
this.layoutSuspendCount = (byte) (this.layoutSuspendCount + 1);
if (this.layoutSuspendCount == 1)
{
this.OnLayoutSuspended();
}
}
由于它没有设置任何公共标志,并且OnLayoutSuspended()方法是内部的,所以无论如何都无法找出控件何时被暂停。
您可以使用新的Suspend和ResumeLayout方法创建树视图的子类,但由于基本方法不是虚拟的,因此很难保证在所有情况下都会调用它们。