Anyone knows how to return a value from Dispatcher.Invoke in wpf? I want to return the selected index for a ComboBox.
Thanks!
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();
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.
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.
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
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;
}
}