我有一个Textblock
,当鼠标悬停在上面时,我想打开一个Popup
。我已使用MultiBinding
至Popup
的IsMouseOver
和TextBlock
的IsMouseOver
将IsOpen
属性绑定,并且它工作正常,除非将鼠标从文本移至弹出窗口时,弹出式窗口会闪烁。WPF .NET Popup - 悬停时打开,如果鼠标悬停,请保持打开
闪烁的原因是事件的执行的发动机罩下的顺序:
鼠标移动从textblock
到popup
- >IsMouseOver
的textblock
设置为false
- >转换器被称为与两个参数是假的 - >才把popup
IsMouseOver
设置为true
- >转换器执行有两个参数是假的,弹出窗口消失了 - >转换称为和执行因为另一个事件是因为弹出的IsMouseOver
提前弹出,此时IsMouseOver的Popup
True
- >弹出窗口再次出现。我曾尝试添加StaysOpen=False
,但它从未关闭/行为与预期不同。
问题:我该如何避免闪烁?
代码:
<Grid>
<ListBox ItemsSource="{Binding RandomNames}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="Name: "
Grid.Column="0"/>
<TextBlock Grid.Column="1"
x:Name="NameBlock"
Text="{Binding}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<Popup x:Name="PopupX"
Grid.Column="1"
PlacementTarget="{Binding ElementName=NameBlock}"
Placement="Bottom">
<!--<Popup.IsOpen>
<MultiBinding Converter="{StaticResource PopupIsOpenConverter}">
<Binding ElementName="PopupX" Path="IsMouseOver" Mode="OneWay" />
<Binding ElementName="NameBlock" Path="IsMouseOver" Mode="OneWay" />
</MultiBinding>
</Popup.IsOpen>-->
<Popup.Style>
<Style TargetType="Popup">
<Setter Property="IsOpen" Value="True" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, ElementName=NameBlock}" Value="False" />
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="False" />
</MultiDataTrigger.Conditions>
<Setter Property="IsOpen" Value="False" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Popup.Style>
<TextBlock Text="{Binding}"
Foreground="Coral" />
</Popup>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
转换代码
[ValueConversion(typeof(bool), typeof(bool))]
public class PopupIsOpenConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values.Any(value => value is bool && (bool) value);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new ActionNotSupportedException();
}
}