2008-09-29 10 views
18

Tôi có một vài nút mà tôi đã sửa đổi giao diện của chúng. Tôi đã đặt chúng như là các nút phẳng với nền và đường viền tùy chỉnh để chúng trông đẹp và không giống các nút bình thường nữa (thực ra, chúng trông giống như các nút Office 2003 bây giờ ;-). Các nút có đường viền một pixel.Làm cách nào để đặt/thay đổi/xóa kiểu tiêu điểm trên Nút trong C#?

Tuy nhiên khi nút được chọn (lấy tiêu điểm thông qua nhấp chuột hoặc thao tác bàn phím như nhấn phím tab) nút đột nhiên nhận được và thêm đường viền xung quanh nó cùng màu, do đó, làm cho nó trở thành đường viền hai pixel. Hơn nữa, khi tôi vô hiệu hóa đường viền một pixel, nút này không nhận được đường viền một pixel trên tiêu điểm.

Trên mạng câu hỏi này được hỏi rất nhiều như 'Làm thế nào tôi có thể vô hiệu hóa tập trung vào một Button', nhưng đó không phải là những gì tôi muốn: sự tập trung nên vẫn tồn tại, chỉ cần không hiển thị theo cách nó hiện nay.

Mọi đề xuất? :-)

Trả lời

0

Chắc chắn bạn có thể tự vẽ nút. Một trong những cờ trạng thái được tập trung.

Vì vậy, trên sự kiện vẽ nếu lá cờ được tập trung đi trước và vẽ nút bạn thích, nếu không, chỉ cần chuyển nó vào phương pháp cơ sở.

+0

Bạn có thể giải thích thêm một chút, vì không có sự kiện Vẽ * nào không? Tuy nhiên, có một sự kiện Paint, nhưng không có cờ trạng thái. =) Tôi hiểu và thích ý tưởng này, chỉ mất một chút khi thực hiện thực tế. –

0

Cân nhắc triển khai mã bản vẽ của riêng bạn cho nút. Bằng cách đó bạn có toàn quyền kiểm soát. Trong quá khứ, tôi đã thực hiện đạo hàm Control của riêng mình rằng tùy chỉnh vẽ nút của tôi và thực hiện tất cả các đặc điểm của nút cho mục đích của tôi, nhưng bạn sẽ có thể ghi đè lên hình ảnh của nút và tự làm, do đó kiểm soát cách nó vẽ ở mọi trạng thái , kể cả khi được tập trung.

30

Đây có phải là hiệu ứng bạn đang tìm kiếm không?

public class NoFocusCueButton : Button 
{ 
    protected override bool ShowFocusCues 
    { 
     get 
     { 
      return false; 
     } 
    } 
} 

Bạn có thể sử dụng lớp nút tùy chỉnh này giống như nút thông thường, nhưng nó sẽ không cho bạn hình chữ nhật thêm vào tiêu điểm.

+2

Cảm ơn bạn đã gợi ý tuyệt vời! Điều này sẽ loại bỏ một hình chữ nhật tiêu điểm màu xám bên trong, nhưng không phải là đường viền một pixel được thêm vào (mà làm cho nó có tổng cộng hai đường viền pixel). –

+2

@Chris Jester-Young: Kiểm tra câu trả lời từ Josh Stribling để ẩn thêm một đường viền pixel. – Marc

1

Đường viền thứ hai được thêm vào là đường viền "nút mặc định" chuẩn của Windows. Bạn có thể nhận thấy rằng nếu bạn tab thông qua hầu hết các hộp thoại với nhiều nút (chẳng hạn như bất kỳ cửa sổ thuộc tính Bảng điều khiển), nút "hai giáp" ban đầu trở thành "bình thường" và nút trong tiêu điểm trở thành "hai cạnh. "

Điều này không nhất thiết phải tập trung vào công việc, mà là một dấu hiệu trực quan của hành động được thực hiện bằng cách nhấn phím Enter.

Nghe có vẻ, với tôi, như bạn không thực sự quan tâm đến nội dung đó. Bạn muốn màn hình hiển thị không có hai đường viền - hoàn toàn dễ hiểu. Công việc nội bộ là giải thích lý do tại sao bạn thấy hành vi này. Bây giờ ... Để thử và sửa chữa nó.

Điều đầu tiên tôi muốn thử - và nhớ rằng, tôi chưa xác thực điều này - là một bản hack. Khi một nút nhận được tiêu điểm (do đó nhận được đường viền đôi), hãy tắt đường viền đơn của bạn. Bạn có thể nhận được hiệu ứng bạn muốn và nó khá đơn giản. (Hook vào Focus sự kiện. Thậm chí tốt hơn, subclass Button và ghi đè OnFocus, sau đó sử dụng phân lớp đó cho các nút tương lai của bạn.)

Tuy nhiên, có thể giới thiệu các hiệu ứng phụ mới, khó xử. Trong tĩnh mạch đó - và vì hacks hiếm khi là câu trả lời hay nhất - tôi phải "chính thức" đề xuất những gì người khác đã nói: Tùy chỉnh vẽ nút. Mặc dù mã ở đây có thể quá mức cần thiết, điều này link at CodeProject thảo luận cách thực hiện điều đó (liên kết VB; bạn sẽ cần dịch). Bạn nên, trong chế độ tùy chỉnh đầy đủ, có thể loại bỏ hoàn toàn biên giới thứ hai đó.

2

Có một cách khác hoạt động tốt cho các nút được tạo kiểu phẳng. Không sử dụng các nút nhưng nhãn. Khi bạn thay thế hoàn toàn giao diện người dùng cho nút, việc sử dụng nút điều khiển hoặc nhãn có quan trọng không quan trọng. Chỉ cần xử lý các nhấp chuột trong cùng một cách.

Điều này làm việc cho tôi, mặc dù không thực hành tuyệt vời nó là một hack tốt và miễn là bạn đặt tên cho nút rõ ràng (và bình luận nguồn) các lập trình viên khác sẽ nhận ý tưởng.

Ryan

0

Thiết lập thuộc tính FocusVisualStyle phụ thuộc để null trong phong cách của bạn, và biên giới rải rác sẽ biến mất.

Từ MSDN: Styling for Focus in Controls, and FocusVisualStyle

Windows Presentation Foundation (WPF) cung cấp hai cơ chế song song cho thay đổi sự xuất hiện hình ảnh của một điều khiển khi nó nhận bàn phím tập trung. Cơ chế đầu tiên là sử dụng các thuộc tính thuộc tính cho các thuộc tính như như IsKeyboardFocused trong kiểu hoặc mẫu được áp dụng cho điều khiển . T cơ chế thứ hai là cung cấp kiểu riêng biệt làm giá trị thuộc tính FocusVisualStyle; các "tập trung visual style" tạo ra một cây thị giác riêng cho một adorner thu hút trên đầu trang của sự kiểm soát, hơn là thay đổi cây thị giác của sự kiểm soát hoặc thành phần giao diện người dùng khác bằng cách thay thế nó. Chủ đề này thảo luận về các tình huống trong đó mỗi cơ chế này là thích hợp.

Các thêm biên giới bạn thấy được xác định bởi FocusVisualStyle và không có trong các mẫu kiểm soát, vì vậy bạn cần phải loại bỏ hoặc ghi đè lên phong cách để loại bỏ biên giới.

+0

Đây là dành cho WPF, không phải Winforms. – DMan

6

Một tùy chọn khác (mặc dù một chút hacktastic) là đính kèm một trình xử lý sự kiện vào sự kiện GotFocus của nút. Trong trình xử lý sự kiện đó, chuyển giá trị False tới phương thức NotifyDefault() của nút. Vì vậy, ví dụ:

void myButton_GotFocus(object sender, EventArgs e) 
{ 
    myButton.NotifyDefault(false); 
} 

Tôi giả định điều này sẽ hoạt động mọi lúc, nhưng tôi chưa thử nghiệm rộng rãi. Nó làm việc cho tôi bây giờ, vì vậy tôi hài lòng với điều đó.

0

Nếu bạn có một textbox và một nút đó trở đi textchange sự kiện của textbox viết button1.focus();

Nó sẽ làm việc.

14

Thực hiện một nút tùy chỉnh:

public partial class CustomButton: Button 
{ 
    public ButtonPageButton() 
    { 
     InitializeComponent(); 

     this.SetStyle(ControlStyles.Selectable, false); 
    } 
} 

Điều đó sẽ thoát khỏi rằng biên giới gây rắc rối!;-)

+0

Điều này làm việc cho tôi và rất đơn giản. – theJerm

+0

Thật không may điều này vô hiệu hóa khả năng tập trung vào nút. Ghi đè 'ShowFocusCues' có vẻ tốt hơn. –

-3

Tôi đã có may mắn chỉ đơn thuần là thiết lập thuộc tính thể đặt tiêu điểm của các nút là sai:

<Button HorizontalAlignment="Left" Margin="0,2" 
     Command="{Binding OpenSuspendedJobCommand, Mode=OneWay}" 
     Focusable="False" 
     Style="{StaticResource ActionButton}" Content="Open Job..." /> 
+1

WPF không giống với WinForms. – Neolisk

19

tôi đã có vấn đề tương tự với viền đôi gây phiền nhiễu, và loạng choạng qua thread này tìm kiếm một câu trả lời ...

Con đường tôi giải quyết này là để thiết lập các BorderSize-0 sau đó vẽ biên giới của riêng tôi trong OnPaint

* Lưu ý: Không phải là toàn bộ nút, chỉ là biên giới

Một ví dụ đơn giản sẽ là:

public class CustomButton : Button 
{ 
    public CustomButton() 
     : base() 
    { 
     // Prevent the button from drawing its own border 
     FlatAppearance.BorderSize = 0; 
     FlatStyle = System.Windows.Forms.FlatStyle.Flat; 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     // Draw Border using color specified in Flat Appearance 
     Pen pen = new Pen(FlatAppearance.BorderColor, 1); 
     Rectangle rectangle = new Rectangle(0, 0, Size.Width - 1, Size.Height - 1); 
     e.Graphics.DrawRectangle(pen, rectangle); 
    } 
} 

Trong trường hợp của tôi, đây là cách tôi đã làm một nút bắt chước một ToolStripButton, nơi biên giới chỉ hiển thị khi bạn di chuột qua nút:

public class ToolButton : Button 
{ 
    private bool ShowBorder { get; set; } 

    public ToolButton() 
     : base() 
    { 
     // Prevent the button from drawing its own border 
     FlatAppearance.BorderSize = 0; 

     // Set up a blue border and back colors for the button 
     FlatAppearance.BorderColor = Color.FromArgb(51, 153, 255); 
     FlatAppearance.CheckedBackColor = Color.FromArgb(153, 204, 255); 
     FlatAppearance.MouseDownBackColor = Color.FromArgb(153, 204, 255); 
     FlatAppearance.MouseOverBackColor = Color.FromArgb(194, 224, 255); 
     FlatStyle = System.Windows.Forms.FlatStyle.Flat; 

     // Set the size for the button to be the same as a ToolStripButton 
     Size = new System.Drawing.Size(23, 22); 
    } 

    protected override void OnMouseEnter(EventArgs e) 
    { 
     base.OnMouseEnter(e); 

     // Show the border when you hover over the button 
     ShowBorder = true; 
    } 

    protected override void OnMouseLeave(EventArgs e) 
    { 
     base.OnMouseLeave(e); 

     // Hide the border when you leave the button 
     ShowBorder = false; 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     // The DesignMode check here causes the border to always draw in the Designer 
     // This makes it easier to place your button 
     if (DesignMode || ShowBorder) 
     { 
      Pen pen = new Pen(FlatAppearance.BorderColor, 1); 
      Rectangle rectangle = new Rectangle(0, 0, Size.Width - 1, Size.Height - 1); 
      e.Graphics.DrawRectangle(pen, rectangle); 
     } 
    } 



    // Prevent Text from being set on the button (since it will be an icon) 
    [Browsable(false)] 
    public override string Text { get { return ""; } set { base.Text = ""; } } 

    [Browsable(false)] 
    public override ContentAlignment TextAlign { get { return base.TextAlign; } set { base.TextAlign = value; } } 
} 
0

Bạn cũng có thể tạo nút ẩn và kích hoạt nút bất cứ khi nào bạn nhấn nút khác.