我喜歡ToolStripProfessionalRenderer風格頗多,但我不喜歡它呈現ToolStripTextBox的方式。在這裏,ToolStripSystemRenderer在IMO中做得更好。現在有沒有辦法將兩種渲染器的行爲結合起來使用文本框的系統風格和其他一切的專業風格?我已成功設法使用專業風格的按鈕和系統風格的休息(通過派生這兩個類)。但ToolStrip中的文本框似乎不由渲染器處理。使用.NET Reflector,這些文本框似乎沒有Paint事件處理程序,儘管它是由ToolStrip.OnPaint方法調用的。我想知道在哪裏可以繪製這樣一個文本框的代碼以及如何將它配置爲像所有其他文本框一樣繪製文本框。如何自定義ToolStripTextBox的渲染?
回答
如果你只是想系統的渲染,最簡單的方法是使用ToolStripControlHost代替:
class ToolStripSystemTextBox : ToolStripControlHost { public ToolStripSystemTextBox : base(new TextBox()) { } [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] [TypeConverter(typeof(ExpandableObjectConverter))] public TextBox TextBox { get { return Control as TextBox; } } }
我已經採取了這裏的簡單的方法,直接暴露潛在的文本框窗體設計器,而不是委託所有的屬性。顯然你可以編寫所有的財產分類代碼,如果你想。另一方面,如果有人想做真正的定製渲染,我會告訴你什麼是ToolStripTextBox。它不直接託管文本框,而是託管一個名爲ToolStripTextBoxControl的私有派生類。該類重寫它的WndProc以直接處理WM_NCPAINT。然後將實際繪圖委託給渲染器,然後檢查渲染器的類型,然後分支到ToolStripTextBoxControl中的不同渲染代碼。這很醜陋。
也可能沒有必要潛入「WndProc」。這是沒有完成它:
真正的問題是你如何做一個「好看」文本框,因爲j__m所描述的,你可以只使用ToolStripControlHost,在您的工具來承載自定義控件跳閘。
這裏更多: http://msdn.microsoft.com/en-us/library/system.windows.forms.toolstripcontrolhost.aspx
而作爲記錄,您可以使用該控件可以是自定義控制。首先,製作一個自定義的TextBox控件是非常棘手的。如果你想去:
public partial class TextBoxOwnerDraw : TextBox
你是在爲巨大的麻煩!但它不一定是。這裏有一個小技巧:
如果您將自定義控件設置爲Panel,然後將TextBox添加到Panel中,然後將Textbox邊框設置爲None ...您可以實現上述結果,並且最重要的是,它只是一個普通的舊文本框,所以剪貼複製粘貼全部作品,右鍵單擊作品!
好吧,這裏是一個很好看的文本框代碼:
public partial class TextBoxOwnerDraw : Panel
{
private TextBox MyTextBox;
private int cornerRadius = 1;
private Color borderColor = Color.Black;
private int borderSize = 1;
private Size preferredSize = new Size(120, 25); // Use 25 for height, so it sits in the middle
/// <summary>
/// Access the textbox
/// </summary>
public TextBox TextBox
{
get { return MyTextBox; }
}
public int CornerRadius
{
get { return cornerRadius; }
set
{
cornerRadius = value;
RestyleTextBox();
this.Invalidate();
}
}
public Color BorderColor
{
get { return borderColor; }
set
{
borderColor = value;
RestyleTextBox();
this.Invalidate();
}
}
public int BorderSize
{
get { return borderSize; }
set
{
borderSize = value;
RestyleTextBox();
this.Invalidate();
}
}
public Size PrefSize
{
get { return preferredSize; }
set
{
preferredSize = value;
RestyleTextBox();
this.Invalidate();
}
}
public TextBoxOwnerDraw()
{
MyTextBox = new TextBox();
this.Controls.Add(MyTextBox);
RestyleTextBox();
}
private void RestyleTextBox()
{
double TopPos = Math.Floor(((double)this.preferredSize.Height/2) - ((double)MyTextBox.Height/2));
MyTextBox.BackColor = Color.White;
MyTextBox.BorderStyle = BorderStyle.None;
MyTextBox.Multiline = false;
MyTextBox.Top = (int)TopPos;
MyTextBox.Left = this.BorderSize;
MyTextBox.Width = preferredSize.Width - (this.BorderSize * 2);
this.Height = MyTextBox.Height + (this.BorderSize * 2); // Will be ignored, but if you use elsewhere
this.Width = preferredSize.Width;
}
protected override void OnPaint(PaintEventArgs e)
{
if (cornerRadius > 0 && borderSize > 0)
{
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
Rectangle cRect = this.ClientRectangle;
Rectangle safeRect = new Rectangle(cRect.X, cRect.Y, cRect.Width - this.BorderSize, cRect.Height - this.BorderSize);
// Background color
using (Brush bgBrush = new SolidBrush(MyTextBox.BackColor))
{
DrawRoundRect(g, bgBrush, safeRect, (float)this.CornerRadius);
}
// Border
using (Pen borderPen = new Pen(this.BorderColor, (float)this.BorderSize))
{
DrawRoundRect(g, borderPen, safeRect, (float)this.CornerRadius);
}
}
base.OnPaint(e);
}
#region Private Methods
private GraphicsPath getRoundRect(int x, int y, int width, int height, float radius)
{
GraphicsPath gp = new GraphicsPath();
gp.AddLine(x + radius, y, x + width - (radius * 2), y); // Line
gp.AddArc(x + width - (radius * 2), y, radius * 2, radius * 2, 270, 90); // Corner (Top Right)
gp.AddLine(x + width, y + radius, x + width, y + height - (radius * 2)); // Line
gp.AddArc(x + width - (radius * 2), y + height - (radius * 2), radius * 2, radius * 2, 0, 90); // Corner (Bottom Right)
gp.AddLine(x + width - (radius * 2), y + height, x + radius, y + height); // Line
gp.AddArc(x, y + height - (radius * 2), radius * 2, radius * 2, 90, 90); // Corner (Bottom Left)
gp.AddLine(x, y + height - (radius * 2), x, y + radius); // Line
gp.AddArc(x, y, radius * 2, radius * 2, 180, 90); // Corner (Top Left)
gp.CloseFigure();
return gp;
}
private void DrawRoundRect(Graphics g, Pen p, Rectangle rect, float radius)
{
GraphicsPath gp = getRoundRect(rect.X, rect.Y, rect.Width, rect.Height, radius);
g.DrawPath(p, gp);
gp.Dispose();
}
private void DrawRoundRect(Graphics g, Pen p, int x, int y, int width, int height, float radius)
{
GraphicsPath gp = getRoundRect(x, y, width, height, radius);
g.DrawPath(p, gp);
gp.Dispose();
}
private void DrawRoundRect(Graphics g, Brush b, int x, int y, int width, int height, float radius)
{
GraphicsPath gp = getRoundRect(x, y, width, height, radius);
g.FillPath(b, gp);
gp.Dispose();
}
private void DrawRoundRect(Graphics g, Brush b, Rectangle rect, float radius)
{
GraphicsPath gp = getRoundRect(rect.X, rect.Y, rect.Width, rect.Height, radius);
g.FillPath(b, gp);
gp.Dispose();
}
#endregion
}
現在的ToolStripControlHost
public partial class ToolStripTextBoxOwnerDraw : ToolStripControlHost
{
private TextBoxOwnerDraw InnerTextBox
{
get { return Control as TextBoxOwnerDraw; }
}
public ToolStripTextBoxOwnerDraw() : base(new TextBoxOwnerDraw()) { }
public TextBox ToolStripTextBox
{
get { return InnerTextBox.TextBox; }
}
public int CornerRadius
{
get { return InnerTextBox.CornerRadius; }
set
{
InnerTextBox.CornerRadius = value;
InnerTextBox.Invalidate();
}
}
public Color BorderColor
{
get { return InnerTextBox.BorderColor; }
set
{
InnerTextBox.BorderColor = value;
InnerTextBox.Invalidate();
}
}
public int BorderSize
{
get { return InnerTextBox.BorderSize; }
set
{
InnerTextBox.BorderSize = value;
InnerTextBox.Invalidate();
}
}
public override Size GetPreferredSize(Size constrainingSize)
{
return InnerTextBox.PrefSize;
}
}
那麼當你要使用它,只需將其添加到工具欄:
ToolStripTextBoxOwnerDraw tBox = new ToolStripTextBoxOwnerDraw();
this.toolStripMain.Items.Add(tBox);
或者您想添加它。如果您在Visual Studio中,預覽窗口支持渲染此控件。
只有一件事要記住,它與實際的文本訪問文本框時,它的:
tBox.ToolStripTextBox.Text;
- 1. 如何自定義JRadioButton的渲染?
- 2. 自定義渲染的Zend_Navigation
- 3. 自定義Zend_Form_Element_Radio的渲染
- 4. 如何強制自定義渲染?
- 5. Rails自定義渲染器
- 6. Jlist自定義渲染器
- 7. MPAndroidChart渲染器如何工作以及如何編寫自定義渲染器?
- 8. 如何實現你自己的自定義DirectShow渲染器?
- 9. 自定義渲染/繪圖的Python GUI
- 10. TinyMCE的自定義標籤渲染
- 11. 控制自定義控件的渲染
- 12. JList的自定義渲染和HTML
- 13. Rails的渲染自定義選項
- 14. 自定義渲染器不渲染Xamarin形式
- 15. 覆蓋<f:ajax>使用自定義渲染器渲染
- 16. 數據表自定義的渲染和自定義過濾器
- 17. SF2 Twig:如何自定義CollectionType中嵌入的CoolectionType的渲染?
- 18. CKEditor渲染角度自定義指令
- 19. 窗體渲染自定義symfony2
- 20. 渲染頁面到自定義輸出
- 21. 自定義單元格渲染JXtreetable
- 22. GlassMapper渲染自定義鏈接字段
- 23. Vue js不渲染自定義組件
- 24. 與自定義路線渲染操作
- 25. Facelet自定義組件 - 防止渲染
- 26. Direct3D或XNA渲染自定義檯球
- 27. 渲染在ASP.NET自定義控件
- 28. Xamarin.Forms +自定義渲染器與Xamarin.iOS/Xamarin.Android
- 29. PopUpButton與TileList和自定義渲染器
- 30. 自定義控件不渲染事件
的WinForms或WPF? – Oskar 2009-11-19 10:08:11
Windows窗體 - [分鐘。 15個字符的計算器] – ygoe 2010-12-23 12:33:28