How to return a value with Dispatcher.Invoke?

后端 未结 5 1980
执念已碎
执念已碎 2020-12-20 10:42

Anyone knows how to return a value from Dispatcher.Invoke in wpf? I want to return the selected index for a ComboBox.

Thanks!

相关标签:
5条回答
  • 2020-12-20 11:23

    I have solved this. The solution is create a custom delegate that returns the desired type like this:

        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();
    
    0 讨论(0)
  • 2020-12-20 11:31

    There's another way that returns value from Invoke():

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

    And by the way, chances are that the initial code (which is working with delegate) won't modify oIsLoaded at all; So I'd rather use a Func<> for returning a value from that kind of function.

    0 讨论(0)
  • 2020-12-20 11:32
    int result = -1;
    
    // this is synchronous
    myCombo.Invoke(() => 
    {
      result = myCombo.SelectedIndex;
    });
    
    return result;
    

    This is, of course, kind of clunky. Better design would be to implement INotifyPropertyChanged in your VM, create a SelectedIndex property and bind the SelectedIndex property of your combo box to it. INPC binds are thread-insensitive (3.5 or 4.0+, I don't remember which), so you can read and update these properties from different threads in your VM without worry.

    0 讨论(0)
  • 2020-12-20 11:38

    You can't do this directly but you can do this.

    Dispatcher.Invoke() actually returns the return value from the delegate you call, so alter your delegate accordingly.

    Return Value

    Type: System.Object The return value from the delegate being invoked or null if the delegate has no return value.

    Source

    0 讨论(0)
  • 2020-12-20 11:43

    This is my method to retrieve selected value for a combobox, how can I say delegate to return value?

        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;
                }
    
        }
    
    0 讨论(0)
提交回复
热议问题