Dot-Net
自定義 Winforms 控制項中的基線對齊線
我有一個帶有文本框的自定義使用者控制項,我想在自定義控制項之外公開基線(文本框中的文本)對齊線。我知道您創建了一個設計器(從 ControlDesigner 繼承)並覆蓋 SnapLines 以訪問對齊線,但我想知道如何獲取自定義使用者控制項公開的控制項的文本基線。
我只是有類似的需求,我這樣解決了:
public override IList SnapLines { get { IList snapLines = base.SnapLines; MyControl control = Control as MyControl; if (control == null) { return snapLines; } IDesigner designer = TypeDescriptor.CreateDesigner( control.textBoxValue, typeof(IDesigner)); if (designer == null) { return snapLines; } designer.Initialize(control.textBoxValue); using (designer) { ControlDesigner boxDesigner = designer as ControlDesigner; if (boxDesigner == null) { return snapLines; } foreach (SnapLine line in boxDesigner.SnapLines) { if (line.SnapLineType == SnapLineType.Baseline) { snapLines.Add(new SnapLine(SnapLineType.Baseline, line.Offset + control.textBoxValue.Top, line.Filter, line.Priority)); break; } } } return snapLines; } }這樣,它實際上為子控制項創建了一個臨時子設計器,以便找出“真正的”基線對齊線在哪裡。
這在測試中似乎表現不錯,但如果 perf 成為一個問題(並且如果內部文本框沒有移動),那麼大部分程式碼都可以提取到 Initialize 方法中。
這也假定文本框是 UserControl 的直接子級。如果有其他影響佈局的控制項,那麼偏移量計算會變得有點複雜。
作為 Miral 答案的更新.. 對於正在尋找如何做到這一點的新人,這裡有一些“缺失的步驟”。:) 上面的 C# 程式碼幾乎可以直接使用,除了更改一些值以引用將被修改的 UserControl。
可能需要的參考資料:
System.Design (@robyaw)
所需用途:
using System.Windows.Forms.Design; using System.Windows.Forms.Design.Behavior; using System.ComponentModel; using System.ComponentModel.Design; using System.Collections;在您的 UserControl 上,您需要以下屬性:
[Designer(typeof(MyCustomDesigner))]然後你需要一個“設計器”類,它將覆蓋 SnapLines:
private class MyCustomerDesigner : ControlDesigner { public override IList SnapLines { get { /* Code from above */ IList snapLines = base.SnapLines; // *** This will need to be modified to match your user control MyControl control = Control as MyControl; if (control == null) { return snapLines; } // *** This will need to be modified to match the item in your user control // This is the control in your UC that you want SnapLines for the entire UC IDesigner designer = TypeDescriptor.CreateDesigner( control.textBoxValue, typeof(IDesigner)); if (designer == null) { return snapLines; } // *** This will need to be modified to match the item in your user control designer.Initialize(control.textBoxValue); using (designer) { ControlDesigner boxDesigner = designer as ControlDesigner; if (boxDesigner == null) { return snapLines; } foreach (SnapLine line in boxDesigner.SnapLines) { if (line.SnapLineType == SnapLineType.Baseline) { // *** This will need to be modified to match the item in your user control snapLines.Add(new SnapLine(SnapLineType.Baseline, line.Offset + control.textBoxValue.Top, line.Filter, line.Priority)); break; } } } return snapLines; } } } }