我有一个带命令绑定的弹出窗口,
<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();
}));
答案 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(); });