2010-03-07 85 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; 
    } 

}