tags:

views:

285

answers:

5

Hi,

I have a popup Gui with command binding,

 <Grid x:Name="popup" Visibility="Hidden" DataContext="{Binding Path=PopupMsg}" >


                    <TextBlock x:Name="tbMessage" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Margin="20,70,10,0"
                           Text="{Binding Path=Message}" FontSize="16"/>

                    <Button x:Name="btnPopupOk" Grid.Row="1" Grid.Column="2" Content="{Binding Path=OkContent}" Margin="10,40,10,10"
                        Command="{Binding}" CommandParameter="true" />
                </Grid>
            </Border>
        </Grid>

in the C# file i bind the command:

   CommandBinding okCommandBinding = new CommandBinding(OkCommand);
   okCommandBinding.Executed += popupButtons_Executed;
    okCommandBinding.CanExecute += okCommandBinding_CanExecute;
    CommandBindings.Add(okCommandBinding);
    btnPopupOk.Command = OkCommand;

Its working fine when I use it from the same Thread, when I get a callback from Web Service which is in a different thread I use Dispatcher to show a message, i can see the new text in the popup but the binding isn't working the button remaining unavailable (CanExecute = false), When I click on the screen with the mouse, the popup update the real value of CanExecute and the button is appear available.

System.Windows.Threading.DispatcherPriority.Normal,
          new Action(
            delegate()
            {
                popup.Visibility = Visibility.Visible;
                popup.Focus();

            }));
A: 

You need to use a dispatcher to get the visibility update to go through the main GUI thread (like you need to use Invoke with WinForms)

See MSDN Forums for details.

Basically something like;

   popup.Dispatcher.Invoke(DispatcherPriority.Normal, delegate() { popup.Visibilty = Visibility.Visible; popup.Focus(); });
Thies
It's hard to tell by the question, but I think he is already doing it, based on the last code section.
ArielBH
A: 

Thanks

I got an error "Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type

Yair

YairT
This should be a comment on the answer it relates to, not another answer.
Richard Szalay
A: 

this is the code snippet I use to fix any cross thread calls when updating a WPF UI.

 this.Dispatcher.BeginInvoke(
            (Action)delegate()
        {
            //Update code goes in here
        });

Hope this helps

Alastair Pitts
+1  A: 

Your issue isn't with threading, it's with what will cause a command to call CanExecute.

Usually only certain gui events will cause routed commands to update, and since WPF doesn't know to call CanExecute when data changes, it doesn't.

To manually cause all routed commands to update, call CommandManager.InvalidateRequerySuggested. If the command is based on the message I'd call it when the message is changed.

Cameron MacFarland
A: 

I had the same issue and Cameron's answer helped me get out of the trouble
thanks ;)