2011-11-14 10 views
1

ユーザが "repeat"という名前のCheckBoxを選択したが、ユーザがCheckBoxのチェックを外すとすぐに関数の呼び出しを停止する必要がある場合、関数を繰り返し呼び出すとします。CheckBoxに応じてループを分割する方法ループ実行中に値をチェックしますか?

CheckBoxの 'Checked'、 'C​​lick'、 'Tap'イベントを使用しようとしましたが、ループが開始されると、チェックボックスの状態の変化は検出されません。

私は、別のボタンの_Clickメソッドの中でループを使用しようとしましたが、Buttonの 'pressed'状態にロックを作成しました。

アイデアは何ですか?

答えて

0

は、ループを使用Timerを使用し、上のチェックボックスの状態に応じてオフを切り替えないでください。

// your loop replacement: a timer 
    Timer timer; 

    // this method is called periodically by the timer - do whatever you want here 
    // but make sure you use proper dispatching when accessing the UI (!) 
    private void MyTimerCallback(object state) 
    { 
     System.Diagnostics.Debug.WriteLine("Action!"); 
    } 

    // this creates and starts the timer 
    private void StartTimer() 
    { 
     // set the timer to call your function every 500ms 
     timer = new Timer(MyTimerCallback, null, 500, 500); 
    } 

    // stop the timer 
    private void StopTimer() 
    { 
     timer.Dispose(); 
    } 

    // Checked handler for the checkbox: start the timer 
    private void checkBox1_Checked(object sender, RoutedEventArgs e) 
    { 
     StartTimer(); 
    } 

    // Unchecked handler for the checkbox: stop the timer 
    private void checkBox1_Unchecked(object sender, RoutedEventArgs e) 
    { 
     StopTimer(); 
    } 

コールバック(「MyTimerCallback」)に関するいくつかの注意事項:

タイマーを作成したスレッド上で実行しない方法。 は、システムによって提供されるThreadPoolスレッドで実行されます。 (出典:Timerのドキュメント)

これは重要であり、あなたは、このメソッドから直接、任意のUI要素にアクセスしないように指示します。代わりに次のようなことをしてください:

textBlock1.Dispatcher.BeginInvoke(() => { textBlock1.Text = "Changed text"; }); 
+0

これは本当にうまくいきました –

+0

良いです。一般的な経験則として、メインスレッドでビジーループを作成しないでください代わりに 'Timer'のようなコールバック機構やスレッドベースの代替手段を使用してください。 –

0

UIスレッドのループでスピンするのは悪い習慣です。代わりに依存関係プロパティにバインドしてから、PropertyChangedCallbackで必要なものを実行してください。

XAML

<!-- MainWindowInstance is the x:Name of this class, you can avoid setting the --> 
<!-- ElementName if you setup a DataContext --> 
<CheckBox Content="Repeat" IsChecked="{Binding ElementName=MainWindowInstance, Path=Checked, Mode=TwoWay}" /> 

コードビハインド

public bool Checked 
{ 
    get { return (bool)GetValue(CheckedProperty); } 
    set { SetValue(CheckedProperty, value); } 
} 

public static readonly DependencyProperty CheckedProperty = DependencyProperty.Register("Checked", typeof(bool), typeof(MainPage), new PropertyMetadata((s, e) => 
{ 
    if ((bool)e.NewValue) 
    { 
     // Checked 
     MessageBox.Show("checkbox checked"); 
    } 
    else 
    { 
     // Unchecked 
    } 
})); 
+0

残念ですが、私はここで初心者です。どのように私はOnPropertyChangedを正確に使用しますか?たとえば、チェックボックスをオンにし、チェックボックスをオフにするたびに、チェックボックスをオンにしてMessageBoxを印刷する必要がある場合、その逆はどうしますか? –

+0

XAMLでは、CheckBox.IsCheckedプロパティを依存関係プロパティのラッパーであるコードビハインドのCheckedプロパティにバインドします。 DependencyProperty.Register()呼び出しを参照してください。 PropertyMetadataコンストラクタは、私の例にも示されているプロパティの値をチェックできるコールバックをとります。 – David

+0

あなたが言ったことを正確に試しました。しかし、XAMLを追加した後、実行中にバックエンドが発生した場合、CheckedPropertyの変更されたイベントは何らかの理由で発生しません。デバッグ領域にメッセージはありません。たぶん私はまだ何か間違っています:( –

関連する問題