2010-03-07 83 views
1

我正在尋找一個按鈕控件,將AutoSize它的圖像。正常按鈕控件不會這樣做。我正在使用C#.Net 2.0。ImageButton將自動調整圖像

例如,我有一個200 x 50像素的按鈕和一個800 x 100像素的圖像。我想調整圖像的大小,使其靠近按鈕文本左側的一點。用PictureBox我可以做到這一點。但是當我在Button上放置PictureBox時非常難看,因爲你不能點擊它。

回答

5

你可以做到這一點,如下所示:

button.Image = Image.FromFile(path); 
button.AutoSize = true; 

例如:或者,您可以創建一個新的按鈕類型,這將改變圖像的大小:

public class AutoSizeButton : Button 
{ 

    public new Image Image 
    { 
     get { return base.Image; } 
     set 
     { 
      Image newImage = new Bitmap(Width, Height); 
      using (Graphics g = Graphics.FromImage(newImage)) 
      { 
       g.DrawImage(value, 0, 0, Width, Height); 
      } 
      base.Image = newImage; 
     } 
    } 
} 

測試:

AutoSizeButton button = new AutoSizeButton(); 
button.Location = new Point(27, 52); 
button.Name = "button"; 
button.Size = new Size(75, 23); 
button.Text = "Test"; 
button.UseVisualStyleBackColor = true; 
button.Image = Image.FromFile(path); 
Controls.Add(button); 
+0

taht自動調整按鈕的形象,而不是圖像的按鈕。 爲了說清楚我會編輯我的問題。 – Kovu 2010-03-07 19:54:57

0

我最初建議使用一個標準的ImageButton,但然後閱讀你的評論,你正試圖按鈕大小 圖片。對於使用一個LinkBut​​ton:

<asp:LinkButton ID="foo" runat="server" OnClick="LinkButton1_Click"> 
    <asp:Image ID="imagefoo" runat="server" ImageUrl="~/Foo.jpg" /> 
</asp:LinkButton> 
4

我一直在尋找在vb.net一個版本的這一點,所以我開始mykhaylo答案,並提高了一點。此代碼調整圖像大小以適合比例,將圖像置於按鈕中,併爲圖像提供內部填充。

此按鈕實際上不使用按鈕的「圖像」屬性,並公開應交替設置的屬性「AutoScaleImage」。

這裏是C#版本 - VB.net底部。請享用!

[System.ComponentModel.DesignerCategory("")] 
public class AutoScaleButton : Button 
{ 

    private Image _AutoScaleImage; 
    public Image AutoScaleImage { 
    get { return _AutoScaleImage; } 
    set { 
     _AutoScaleImage = value; 
     if (value != null) 
     this.Invalidate(); 
    } 
    } 

    private int _AutoScaleBorder; 
    public int AutoScaleBorder { 
    get { return _AutoScaleBorder; } 
    set { 
     _AutoScaleBorder = value; 
     this.Invalidate(); 
    } 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
    base.OnPaint(e); 
    DrawResizeImage(ref e.Graphics); 
    } 


    private void DrawResizeImage(Graphics g) 
    { 
    if (_AutoScaleImage == null) 
     return; 
    int iB = AutoScaleBorder; 
    int iOff = 0; 
    Rectangle rectLoc = default(Rectangle); 
    Rectangle rectSrc = default(Rectangle); 

    Size sizeDst = new Size(Math.Max(0, this.Width - 2 * iB), 
      Math.Max(0, this.Height - 2 * iB)); 
    Size sizeSrc = new Size(_AutoScaleImage.Width, 
      _AutoScaleImage.Height); 
    double ratioDst = sizeDst.Height/sizeDst.Width; 
    double ratioSrc = sizeSrc.Height/sizeSrc.Width; 

    rectSrc = new Rectangle(0, 0, sizeSrc.Width, sizeSrc.Height); 

    if (ratioDst < ratioSrc) { 
     iOff = (sizeDst.Width - 
     (sizeDst.Height * sizeSrc.Width/sizeSrc.Height))/2; 
     rectLoc = new Rectangle(iB + iOff, 
      iB, 
      sizeDst.Height * sizeSrc.Width/sizeSrc.Height, 
      sizeDst.Height); 
    } else { 
     iOff = (sizeDst.Height - (sizeDst.Width * sizeSrc.Height/sizeSrc.Width))/2; 
     rectLoc = new Rectangle(iB, 
      iB + iOff, 
      sizeDst.Width, 
      sizeDst.Width * sizeSrc.Height/sizeSrc.Width); 
    } 

    g.DrawImage(_AutoScaleImage, rectLoc, rectSrc, GraphicsUnit.Pixel); 

    } 

} 

還是我原來的VB.NET版本。

<System.ComponentModel.DesignerCategory("")> _ 
Public Class AutoScaleButton 
    Inherits Button 

    Private _AutoScaleImage As Image 
    Public Property AutoScaleImage() As Image 
    Get 
     Return _AutoScaleImage 
    End Get 
    Set(value As Image) 
     _AutoScaleImage = value 
     If value IsNot Nothing Then Me.Invalidate() 
    End Set 
    End Property 

    Private _AutoScaleBorder As Integer 
    Public Property AutoScaleBorder() As Integer 
    Get 
     Return _AutoScaleBorder 
    End Get 
    Set(ByVal value As Integer) 
     _AutoScaleBorder = value 
     Me.Invalidate() 
    End Set 
    End Property 

    Protected Overrides Sub OnPaint(e As PaintEventArgs) 
    MyBase.OnPaint(e) 
    DrawResizeImage(e.Graphics) 
    End Sub 

    Private Sub DrawResizeImage(ByRef g As Graphics) 

    If _AutoScaleImage Is Nothing Then Exit Sub 
    Dim iB As Integer = AutoScaleBorder, iOff As Integer = 0 
    Dim rectLoc As Rectangle, rectSrc As Rectangle 

    Dim sizeDst As Size = New Size(Math.Max(0, Me.Width - 2 * iB), Math.Max(0, Me.Height - 2 * iB)) 
    Dim sizeSrc As Size = New Size(_AutoScaleImage.Width, _AutoScaleImage.Height) 
    Dim ratioDst As Double = sizeDst.Height/sizeDst.Width 
    Dim ratioSrc As Double = sizeSrc.Height/sizeSrc.Width 

    rectSrc = New Rectangle(0, 0, sizeSrc.Width, sizeSrc.Height) 

    If ratioDst < ratioSrc Then 
     iOff = (sizeDst.Width - (sizeDst.Height * sizeSrc.Width/sizeSrc.Height))/2 
     rectLoc = New Rectangle(iB + iOff, iB, _ 
           sizeDst.Height * sizeSrc.Width/sizeSrc.Height, _ 
           sizeDst.Height) 
    Else 
     iOff = (sizeDst.Height - (sizeDst.Width * sizeSrc.Height/sizeSrc.Width))/2 
     rectLoc = New Rectangle(iB, iB + iOff, _ 
           sizeDst.Width, _ 
           sizeDst.Width * sizeSrc.Height/sizeSrc.Width) 
    End If 

    g.DrawImage(_AutoScaleImage, rectLoc, rectSrc, GraphicsUnit.Pixel) 

    End Sub 

End Class 
+0

代碼不會編譯,'DrawResizeImage(ref e.Graphics);'拋出一個錯誤。然而,修正它(不需要在'ref'中,在C#中,除了值類型以外的所有對象都是通過引用傳遞的),這正是我正在尋找的。 – 2014-01-27 07:41:21

2
public class ExtButton : Button 
{ 

    public new Image Image 
    { 
     get { return base.Image; } 
     set { 
      base.Image = ScaleImage(value, this.Width, this.Height); 
     } 
    } 

    private Image ScaleImage(Image image, int maxWidth, int maxHeight) 
    { 
     var ratioX = (double)maxWidth/image.Width; 
     var ratioY = (double)maxHeight/image.Height; 
     var ratio = Math.Min(ratioX, ratioY); 

     var newWidth = (int)(image.Width * ratio); 
     var newHeight = (int)(image.Height * ratio); 

     var newImage = new Bitmap(newWidth, newHeight); 
     Graphics.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight); 
     return newImage; 
    } 

}