WPF Gui从不同的Thread刷新

时间:2009-08-13 08:53:40

标签: .net wpf

我有一个带命令绑定的弹出窗口,

 <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> 

在C#文件中我绑定命令:

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

当我从同一个线程使用它时工作正常,当我从Web Service获得回调时,我在使用Dispatcher来显示消息,我可以在弹出窗口中看到新文本但是绑定是不同的线程“按钮保持不可用(CanExecute = false)”,当我用鼠标点击屏幕时,弹出窗口会更新CanExecute的实际值,并且该按钮显示为可用。

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

            }));  

3 个答案:

答案 0 :(得分:12)

这是我在更新WPF UI时用来修复任何跨线程调用的代码片段。

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

希望这有帮助

答案 1 :(得分:2)

您的问题不在于线程,而在于会导致命令调用CanExecute

通常只有某些gui事件会导致路由命令更新,并且由于WPF在数据发生变化时不知道调用CanExecute,因此不会。{/ p>

要手动使所有路由命令更新,请致电CommandManager.InvalidateRequerySuggested。如果该命令基于我在消息发生变化时调用的消息。

答案 2 :(得分:1)

您需要使用调度程序来获取可见性更新以通过主GUI线程(就像您需要使用Invoke with WinForms)

有关详细信息,请参阅MSDN Forums

基本上像是;

   popup.Dispatcher.Invoke(DispatcherPriority.Normal, delegate() { popup.Visibilty = Visibility.Visible; popup.Focus(); });