我在TextBlock
中加载了ContentControl
,并在Hyperlink
的{{1}}集合中添加了Inlines
作为对象。
如果我订阅了设置TextBlock
属性的ContentControl.PreviewMouseUp
事件的处理程序,则在第一次单击链接时不会引发ContentControl.Foreground
和RequestNavigate
事件。如果再次单击该链接,则会引发事件。
如果事件未订阅,或者处理程序什么都不做,那么一切正常。
初始化代码(在窗口构造函数中,Click
之后):
InitializeComponent()
事件处理程序如下:
var run = new Run("Google");
Hyperlink hyperlink = new Hyperlink(run);
hyperlink.Click += hyperlink_Click;
hyperlink.RequestNavigate += hyper_RequestNavigate;
hyperlink.NavigateUri = new Uri("http://www.google.com");
textBlock.Inlines.Clear();
textBlock.Inlines.Add(hyperlink);
XAML如下:
private void hyper_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
System.Diagnostics.Process.Start(e.Uri.ToString());
}
void contentControl_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
contentControl.Foreground = Brushes.Green;
}
void hyperlink_Click(object sender, RoutedEventArgs e)
{
}
注意:如果<Grid>
<ContentControl Name="contentControl">
<TextBlock Name="textBlock"
Width="200"
Height="30" />
</ContentControl>
</Grid>
处理程序已更改,以便始终更改颜色(例如,创建一个选择两种不同颜色的PreviewMouseUp
,并在每次调用处理程序时切换),事件从未提出过。 E.g:
bool
有没有办法让private bool _toggle;
void contentControl_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
contentControl.Foreground = _toggle ? Brushes.Red : Brushes.Green;
_toggle = !_toggle;
}
处理程序设置颜色,但第一次点击链接时仍然会引发PreviewMouseUp
和RequestNavigate
个事件?
答案 0 :(得分:1)
我不知道完全这里发生了什么,但从症状中可以清楚地看到,有一些关于更改ContentControl.Foreground
属性的内容会中断鼠标事件的正常处理。当您设置属性值时,这会导致WPF确定该事件应该被忽略(可能它将属性更改视为已处理事件的指示),因此通常稍后将引发的事件不在提出的事实。
鉴于此,在我看来,最明显的解决方法是延迟属性值的变化,直到鼠标事件实际上已经完全处理完毕,包括提升这些事件。我能想到的 最明显的方法是使用Dispatcher
来稍后调用操作。
即。通过使用Dispatcher.InvokeAsync()
,我们可以确保在完成属性更改之前完全处理鼠标事件本身的处理,因为调度程序正忙于处理鼠标事件,并且无法运行调用的委托直到完成鼠标事件。
这看起来像这样:
void contentControl_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
Dispatcher.InvokeAsync(() =>
{
contentControl.Foreground = Brushes.Green;
});
}
如果您将PreviewMouseUp
处理程序更改为上述处理程序,您应该会看到即使第一次单击鼠标也会引发事件。