web-dev-qa-db-ja.com

Dispatcher.Invokeで値を返す方法は?

Dispatcher . Invoke in wpf から値を返す方法を知っている人はいますか? ComboBox の選択されたインデックスを返したい。

ありがとう!

30
toni
int result = -1;

// this is synchronous
myCombo.Invoke(() => 
{
  result = myCombo.SelectedIndex;
});

return result;

もちろん、これはちょっと不格好です。より良い設計は、VMにINotifyPropertyChangedを実装し、SelectedIndexプロパティを作成して、コンボボックスのSelectedIndexプロパティをそれにバインドすることです。 INPCバインドはスレッドに依存しないため(3.5または4.0+、どちらかは覚えていません)、VM)のさまざまなスレッドからこれらのプロパティを読み取って更新できます。

30
Will

Invoke()から値を返す別の方法があります。

object oIsLoaded = container.Dispatcher.Invoke( new Func<bool> ( () =>
    {
        return container.IsLoaded;
    })
);

ちなみに、(デリゲートで機能している)初期コードがoIsLoadedをまったく変更しない可能性があります。だから私はむしろ Func<> その種の関数から値を返すため。

30
user216652

これは、コンボボックスの選択された値を取得するための私の方法ですが、値を返すためにデリゲートを言うにはどうすればよいですか?

    private object getValueCB(System.Windows.Controls.ComboBox cb)
    {
        object obj;


            if (!cb.Dispatcher.CheckAccess())
            {
                obj = cb.Dispatcher.Invoke(
                  System.Windows.Threading.DispatcherPriority.Normal,
                  new Action(
                    delegate()
                    {
                        obj = cb.SelectedValue;
                    }
                ));

                return obj;
            }
            else
            {
                return obj = cb.SelectedValue;
            }

    }
2
toni

私はこれを解決しました。解決策は、次のように目的のタイプを返すカスタムデリゲートを作成することです。

    private object GetValueCB(System.Windows.Controls.ComboBox cb)
    {
        object obj = null;


            if (!cb.Dispatcher.CheckAccess())
            {
                obj = cb.Dispatcher.Invoke(
                  System.Windows.Threading.DispatcherPriority.Normal,
                  (MyDelegate)
                    delegate()
                    {
                        return (obj = cb.SelectedValue);
                    }
                );

                return obj;
            }
            else
            {
                return obj = cb.SelectedValue;
            }

    }

    public delegate object MyDelegate();
1
toni

これを直接行うことはできませんが、行うことはできます。

Dispatcher.Invoke()は、実際には呼び出したデリゲートからの戻り値を返すため、それに応じてデリゲートを変更します。

戻り値

タイプ:System.Object呼び出されているデリゲートからの戻り値。デリゲートに戻り値がない場合はnull。

ソース

1
Chris