2009-10-30 15 views
6

tôi đã xử lý được nêu ra một sự kiện KeyDown trong một điều khiển người dùng khi tôi tự hỏi nếu nó tồn tại một thư viện cho gõ mã thông thạo để xử lý sự kiện nhưCó cách tiếp cận thông thạo để xử lý sự kiện WinForm không?

editor.When(Keys.F).IsDown().With(Keys.Control).Do((sender, e) => ShowFindWindow()); 

Liệu rằng tồn tại?

+0

Ý tưởng tuyệt vời! Tôi đã không thấy bất cứ điều gì như thế này, có lẽ Jeremy Miller đã làm một số công việc trên StoryTeller (http://storyteller.tigris.org/source/browse/storyteller/trunk/)? –

Trả lời

5

Tôi quyết định đây là một thách thức và điều này có thể cho tôi biết Fluent là gì, vì vậy tôi đã mã hóa một lớp bàn phím Fluent. Tôi không nghĩ rằng tôi tuân theo tất cả các cấu trúc và quy tắc ngôn ngữ thông thạo, nhưng nó hoạt động.

phương pháp khuyến nông Helper

/// <summary> 
/// Provides a set of static (Shared in Visual Basic) methods for starting a fluent expression on a <see cref="System.Windows.Form.Control"/> object. 
/// </summary> 
public static class ControlExtensions 
{ 
    /// <summary> 
    /// Starts a fluent expression that occurs when a key is pressed. 
    /// </summary> 
    /// <param name="control">The control on which the fluent keyboard expression is occuring.</param> 
    /// <param name="keys">The key when it will happen.</param> 
    /// <returns>A <see cref="KeyboardFluent"/> object that makes it possible to write a fluent expression.</returns> 
    public static KeyboardFluent When(this Control control, Keys keys) 
    { 
     return new KeyboardFluent(control).When(keys); 
    } 
} 

Các thông thạo lớp

/// <summary> 
/// Represents a fluent expression for handling keyboard event. 
/// </summary> 
public class KeyboardFluent 
{ 
    /// <summary> 
    /// The control on which the fluent keyboard expression is occuring. 
    /// </summary> 
    private Control control; 

    /// <summary> 
    /// The KeyDown and KeyUp handler. 
    /// </summary> 
    private KeyEventHandler keyHandler; 

    /// <summary> 
    /// Stores if the IsDown method was called and that the KeyDown event is registered. 
    /// </summary> 
    private bool isDownRegistered = false; 

    /// <summary> 
    /// Stores if the IsUp method was called and that the KeyUp event is registered. 
    /// </summary> 
    private bool isUpRegistered = false; 

    /// <summary> 
    /// The list of keys that will make the actions be executed when they are down or up. 
    /// </summary> 
    private List<Keys> triggerKeys; 

    /// <summary> 
    /// The modifiers keys that must be down at the same time than the trigger keys for the actions to be executed. 
    /// </summary> 
    private Keys modifiers; 

    /// <summary> 
    /// The list of actions that will be executed when the trigger keys and modifiers are down or up. 
    /// </summary> 
    private List<Action<object, KeyEventArgs>> actions; 

    /// <summary> 
    /// Initializes a new instance of the <see cref="KeyboardFluent"/> class. 
    /// </summary> 
    /// <param name="control">The control on which the fluent keyboard expression is occuring.</param> 
    public KeyboardFluent(Control control) 
    { 
     this.control = control; 
     this.triggerKeys = new List<Keys>(); 
     this.actions = new List<Action<object, KeyEventArgs>>(); 
     this.keyHandler = new KeyEventHandler(OnKeyHandler); 
    } 

    /// <summary> 
    /// Handles the KeyDown or KeyUp event on the control. 
    /// </summary> 
    /// <param name="sender">The control on which the event is occuring.</param> 
    /// <param name="e">A <see cref="KeyEventArgs"/> that gives information about the keyboard event.</param> 
    private void OnKeyHandler(object sender, KeyEventArgs e) 
    { 
     if (this.triggerKeys.Contains(e.KeyCode) && e.Modifiers == this.modifiers) 
     { 
      this.actions.ForEach(action => action(sender, e)); 
     } 
    } 

    /// <summary> 
    /// Makes the keyboard event occured when a key is pressed down. 
    /// </summary> 
    /// <returns>Returns itself to allow a fluent expression structure.</returns> 
    public KeyboardFluent IsDown() 
    { 
     if (!isDownRegistered) 
     { 
      this.control.KeyDown += this.keyHandler; 
      isDownRegistered = true; 
     } 
     return this; 
    } 

    /// <summary> 
    /// Makes the keyboard event occured when a key is pressed up. 
    /// </summary> 
    /// <returns>Returns itself to allow a fluent expression structure.</returns> 
    public KeyboardFluent IsUp() 
    { 
     if (!isUpRegistered) 
     { 
      this.control.KeyUp += this.keyHandler; 
      isUpRegistered = true; 
     } 
     return this; 
    } 

    /// <summary> 
    /// Creates a new trigger on a key. 
    /// </summary> 
    /// <param name="key">The key on which the actions will occur.</param> 
    /// <returns>Returns itself to allow a fluent expression structure.</returns> 
    public KeyboardFluent When(Keys key) 
    { 
     this.triggerKeys.Add(key); 
     return this; 
    } 

    /// <summary> 
    /// Adds a modifier filter that is checked before the action are executed. 
    /// </summary> 
    /// <param name="modifiers">The modifier key.</param> 
    /// <returns>Returns itself to allow a fluent expression structure.</returns> 
    public KeyboardFluent With(Keys modifiers) 
    { 
     this.modifiers |= modifiers; 
     return this; 
    } 

    /// <summary> 
    /// Executes the action when the specified keys and modified are either pressed down or up. 
    /// </summary> 
    /// <param name="action">The action to be executed.</param> 
    /// <returns>Returns itself to allow a fluent expression structure.</returns> 
    public KeyboardFluent Do(Action<object, KeyEventArgs> action) 
    { 
     this.actions.Add(action); 
     return this; 
    } 
} 

bây giờ tôi có thể gõ

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 

     this.When(Keys.F).With(Keys.Control).IsDown().Do((sender, e) => MessageBox.Show(e.KeyData.ToString())); 
    } 
} 

và nó sẽ hiển thị bảng thông báo chỉ khi Ctrl + F là xuống.

2

.NET 4 sẽ giới thiệu khung phản ứng (IObservable<T>, IObserver<T> và các loại tiện ích trợ giúp) sẽ cung cấp chính xác điều này.

+0

Khung phản ứng không cung cấp giao diện thông thạo cho việc này. Nó cung cấp LINQ cho các sự kiện, đó là khá khác nhau. –

+0

Hôm nay, tôi tình cờ gặp một bài viết trên Khung Rx và nó có sẵn trên .NET Framework 3.5 sp1. Tôi đã cố gắng làm điều tương tự và nó hoạt động hoàn hảo với nhiều tùy chọn hơn. –

3

Tôi đã tải xuống Reactive Extension Framework cho .Net Framework 3.5 SP1.

tôi đã có thể làm tương tự:

Observable.FromEvent<KeyEventArgs>(this, "KeyDown") 
    .Where(e => e.EventArgs.KeyCode == Keys.F && e.EventArgs.Modifiers == Keys.Control) 
    .Subscribe(e => MessageBox.Show(e.EventArgs.KeyData.ToString())); 

Đây là một số công cụ khá mạnh mẽ.

Các vấn đề liên quan