2011-07-12 26 views
0

TextBoxコントロールを拡張して、指定された遅延でカスタムイベントを発生させます。ここでカスタムイベントの遅延の発生

は私が持っているコードは、これまでのところです:

public class DelayTextBox : TextBox 
{ 
    private Timer _delayTimer; 
    private int _threshold = 1000; 

    public DelayTextBox() 
    { 
     _delayTimer = new Timer(_threshold); 
     _delayTimer.Elapsed += new ElapsedEventHandler(_delayTimer_Elapsed); 
    } 

    public int Delay 
    { 
     set { _threshold = value; } 
    } 

    private void _delayTimer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     _delayTimer.Stop(); 
     RaiseDelayedTextChangedEvent(); 
    } 

    protected override void OnTextChanged(TextChangedEventArgs e) 
    { 
     _delayTimer.Stop(); 
     _delayTimer.Start(); 
    } 

    private static readonly RoutedEvent DelayedTextChangedEvent = EventManager.RegisterRoutedEvent(
    "DelayedTextChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DelayTextBox)); 

    public event RoutedEventHandler DelayedTextChanged 
    { 
     add { AddHandler(DelayedTextChangedEvent, value); } 
     remove { RemoveHandler(DelayedTextChangedEvent, value); } 
    } 

    private void RaiseDelayedTextChangedEvent() 
    { 
     RoutedEventArgs newEventArgs = new RoutedEventArgs(DelayTextBox.DelayedTextChangedEvent); 
     RaiseEvent(newEventArgs); 
    } 
} 

問題は、私はRaiseDelayedTextChangedEvent()を発射するたびに、私は私に

を言って、例外を取得することである「呼び出し元のスレッドがアクセスすることはできませんこのオブジェクトは異なった スレッドがそれを所有しているためです。

例外がスローされ、ここで:

private void RaiseDelayedTextChangedEvent() 
    { 
     RoutedEventArgs newEventArgs = new RoutedEventArgs(DelayTextBox.DelayedTextChangedEvent); 
     RaiseEvent(newEventArgs); 
    } <---- Here 

答えて

0

あなたはSTAスレッドでイベントを発生させるディスパッチャを使用する必要があります。

この資料では、タイマーが別のスレッドで実行されるためですhttp://www.switchonthecode.com/tutorials/working-with-the-wpf-dispatcher

private void RaiseDelayedTextChangedEvent() 
    { 
     RoutedEventArgs newEventArgs = new RoutedEventArgs(DelayTextBox.DelayedTextChangedEvent); 

     this.Dispatcher.BeginInvoke(
       System.Windows.Threading.DispatcherPriority.Normal, 
       (UpdateTheUI)delegate(RoutedEventArgs eArgs) 
       { 
        RaiseEvent(eArgs); 
       }, newEventArgs); 

    } 
+0

この場合、それは状況を複雑にしています。 Andreasは明示的にコード内に新しいスレッドを作成していないため、DispatcherTimerを使用する方がはるかに簡単です。 –

+0

この場合、あなたの答えはより良いですが、これは別の方法です。 –

+0

素晴らしい。魅力的に働いた。ありがとう:) – Andreas

2

を持っているスレッドの問題を説明し、(あなたの例外が言うように)UIは、そのスレッドから変更することはできません。代わりにDispatcherTimerを使用してみてください。ここで詳細を知ることができます:http://code.dortikum.net/2008/08/06/timer-vs-dispatchertimer-in-wpf/

関連する問題