Dot-Net

自定義 Winforms 控制項中的基線對齊線

  • September 18, 2008

我有一個帶有文本框的自定義使用者控制項,我想在自定義控制項之外公開基線(文本框中的文本)對齊線。我知道您創建了一個設計器(從 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;
}

   }
 }
}

引用自:https://stackoverflow.com/questions/93541