2015-02-12 15 views
9

It's a rounded edges buttoncạnh tròn trong nút C# (WinForms)

Xin chào, thông qua một số nghiên cứu trên đây và các trang web khác, tôi đã thực hiện một nút cạnh tròn.

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 
    Rectangle Rect = new Rectangle(0, 0, this.Width, this.Height); 
    GraphicsPath GraphPath = new GraphicsPath(); 
    GraphPath.AddArc(Rect.X, Rect.Y, 50, 50, 180, 90); 
    GraphPath.AddArc(Rect.X + Rect.Width - 50, Rect.Y, 50, 50, 270, 90); 
    GraphPath.AddArc(Rect.X + Rect.Width - 50, Rect.Y + Rect.Height - 50, 50, 50, 0, 90); 
    GraphPath.AddArc(Rect.X, Rect.Y + Rect.Height - 50, 50, 50, 90, 90); 
    this.Region = new Region(GraphPath); 
} 

Vấn đề tôi đang phải đối mặt là của nút "xanh nổi bật": Nó cho thấy trên hầu hết các nút, nhưng nó không hiển thị trên các cạnh tròn, vì vậy nút của tôi là một phần nổi bật và một phần không được đánh dấu (trên các cạnh). Tôi có thể làm gì để giải quyết vấn đề này? Cảm ơn bạn.

PS: Tôi không thể sử dụng WPF. Ứng dụng này dành cho một máy tính rất cũ; vì vậy, xin vui lòng, không đề nghị nó. Ngoài ra, khách hàng không có tiền để có được một máy tính mới hơn.

+3

Side lưu ý: bạn nên thiết lập khu vực chỉ một lần, không trên mọi loại sơn. –

+0

@LucasTrzesniewski Cảm ơn bạn. – soulblazer

+0

Xem câu trả lời cập nhật của tôi! – TaW

Trả lời

9

Đây là một cách nhanh chóng, bạn có thể muốn điều chỉnh tốt và tối ưu hóa khá một vài chi tiết ..

class RoundedButton : Button 
{ 
    GraphicsPath GetRoundPath(RectangleF Rect, int radius) 
    { 
     float r2 = radius/2f; 
     GraphicsPath GraphPath = new GraphicsPath(); 

     GraphPath.AddArc(Rect.X, Rect.Y, radius, radius, 180, 90); 
     GraphPath.AddLine(Rect.X + r2, Rect.Y, Rect.Width - r2, Rect.Y); 
     GraphPath.AddArc(Rect.X + Rect.Width - radius, Rect.Y, radius, radius, 270, 90); 
     GraphPath.AddLine(Rect.Width, Rect.Y + r2, Rect.Width, Rect.Height - r2); 
     GraphPath.AddArc(Rect.X + Rect.Width - radius, 
         Rect.Y + Rect.Height - radius, radius, radius, 0, 90); 
     GraphPath.AddLine(Rect.Width - r2, Rect.Height, Rect.X + r2, Rect.Height); 
     GraphPath.AddArc(Rect.X, Rect.Y + Rect.Height - radius, radius, radius, 90, 90); 
     GraphPath.AddLine(Rect.X, Rect.Height - r2, Rect.X, Rect.Y + r2); 

     GraphPath.CloseFigure(); 
     return GraphPath; 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 
     RectangleF Rect = new RectangleF(0, 0, this.Width, this.Height); 
     GraphicsPath GraphPath = GetRoundPath(Rect, 50); 

     this.Region = new Region(GraphPath); 
     using (Pen pen = new Pen(Color.CadetBlue, 1.75f)) 
     { 
      pen.Alignment = PenAlignment.Inset; 
      e.Graphics.DrawPath(pen, GraphPath); 
     } 
    } 
} 

Rõ ràng, vì chúng ta có một lớp chúng ta có thể bộ nhớ cache GraphicsPath trong một biến lớp. Và dĩ nhiên bạn chọn màu ..

enter image description here

+0

Đó là quá phiền hà để làm cho các ứng dụng cho máy tính cũ ... Cảm ơn bạn đã chia sẻ mã này! – soulblazer

+0

Đây là một giải pháp tốt. Nhưng đường biên giới vẫn không ấn tượng lắm. Trên thực tế quá lame, nó làm cho tôi không sử dụng này. –

+0

Vâng, người ta có thể thử một Graphics.SmoothingMode nhưng bạn đang phải: Winforms là không tốt tại glitz .. – TaW

0

Ít tự vẽ nó, tôi không nghĩ có bất cứ điều gì bạn có thể làm. Lôgic sơn nút cơ sở không được viết là "hiển thị điểm nhấn màu xanh xung quanh phần như vậy của bất kỳ vùng cửa sổ nào". Thay vào đó, nó được viết với loại vùng mong đợi - một hình chữ nhật. Vì vậy, sơn cơ sở luôn luôn sẽ vẽ một hình chữ nhật thành một hình dạng cắt. Bạn sẽ có một thời gian dễ dàng hơn trong những điều như vậy trong WPF.

+0

Cố gắng nói điều đó với khách hàng mong đợi ứng dụng trở nên đẹp, nhưng không muốn mua một máy tính mới hơn, có khả năng đồ họa hơn. Tôi không biết làm thế nào để gõ một số ý nghĩa vào anh ta. Chỉ vì một máy tính là một máy tính, nó không có nghĩa là nó sẽ hữu ích cho mọi thứ. – soulblazer

+2

Ngoài ra, tôi nhận thấy rằng bạn (giống như tài liệu tại https://msdn.microsoft.com/en-us/library/system.windows.forms.control.region.aspx) đang thiết lập thuộc tính Region trong trình xử lý sự kiện Paint của bạn . Bạn có thể chỉ muốn làm điều này trong một trình xử lý cho sự kiện Layout. Tài liệu này có một ví dụ nghèo nàn và tôi sẽ để lại một bình luận ở đó để nêu rõ. :) –

+0

@Michael tốt bắt, đó là một số lời khuyên khủng khiếp từ các tài liệu ...: - \ –

0

Bạn có thể sử dụng một trình duyệt khác, làm cho một nút với HTML và CSS, sau đó sử dụng webbrowser.DocumentText = "your html";

+0

Bạn có thể thực sự sử dụng một WebBrowser trên WinForms? – soulblazer

+0

@Soulblazer Tại sao không? – isaque

+0

Chỉ cần tự hỏi. Tôi chưa bao giờ nghe nói rằng có thể cho đến bây giờ. Tôi nghĩ bạn đã đọc sai câu hỏi hoặc một cái gì đó. Xin lỗi về điều đó và cảm ơn bạn. – soulblazer