【发布时间】:2017-10-10 16:20:52
【问题描述】:
我有一个Textblock,当鼠标悬停在它上面时,我想在它上面打开一个Popup。我已经使用MultiBinding 将IsOpen 属性绑定到Popup 的IsMouseOver 和TextBlock 的IsMouseOver,并且它可以工作,除非将鼠标从文本移动到弹出窗口,弹出闪烁。
闪烁的原因是幕后事件的执行顺序:
鼠标从textblock 移动到popup-->textblock 的IsMouseOver 设置为false --> 调用转换器,两个参数都为 false -->只有在popup 的IsMouseOver 设置为true --> 转换器执行,两个参数都为false,弹出窗口消失--> 转换器调用 和再次执行,因为之前为弹出窗口的IsMouseOver 引发了另一个事件,这次Popup True 的 IsMouseOver --> 弹出窗口再次出现。我尝试添加 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();
}
}
【问题讨论】: