2012-08-06 39 views
2

我基本上试图在按钮悬停上实现弹出窗口。当用户悬停在按钮上时,我希望弹出窗口出现。当他们不是,我只想要标签出现。这有点像一个工具提示,只不过我不想让Popup在经过一段时间后走开。我还挺有工作用的按钮控件模板有两个注意事项:弹出对齐PlacementTarget的中心和底部

  1. 当我将鼠标悬停在按钮下方的面积,屏幕弹出和标签之间的闪烁。
  2. 我希望弹出对齐底部和中心。

XAML代码:

<Window> 
    <Window.Resources> 
     <Style x:Key="LabelStyle" TargetType="Label"> 
      <Setter Property="Margin" Value="0, 0, 0, 5" /> 
      <Setter Property="Width" Value="58" /> 
      <Setter Property="Height" Value="28" /> 
      <Setter Property="Padding" Value="1, 0, 1, 0" /> 
     </Style> 

     <ControlTemplate x:Key="ButtonControlTemplate" TargetType="Button"> 
      <StackPanel> 
       <Button Width="48" Height="48" Background="White" Name="ItemButton"> 
        <ContentPresenter Content="{TemplateBinding Property=ContentControl.Content}" /> 
       </Button> 
       <Label Style="{StaticResource LabelStyle}" VerticalContentAlignment="Top" HorizontalContentAlignment="Center" Name="ItemLabel"> 
        <TextBlock TextWrapping="Wrap" TextAlignment="Center" FontSize="11" LineHeight="13" LineStackingStrategy="BlockLineHeight"> 
         Hello World! 
        </TextBlock> 
       </Label> 
       <Popup Name="ItemPopup" Placement="Bottom" PlacementTarget="{Binding ElementName=ItemButton}"> 
        <TextBlock Background="Red">Hello World!</TextBlock> 
       </Popup> 
      </StackPanel> 
      <ControlTemplate.Triggers> 
       <Trigger SourceName="ItemButton" Property="IsMouseOver" Value="True"> 
        <Setter TargetName="ItemLabel" Property="Visibility" Value="Hidden" /> 
        <Setter TargetName="ItemPopup" Property="IsOpen" Value="True" /> 
       </Trigger> 
      </ControlTemplate.Triggers> 
     </ControlTemplate> 
    </Window.Resources> 

    <StackPanel> 
     <Button Background="Green" Template="{StaticResource ButtonControlTemplate}"> 
      <Image Source="http://leduc998.files.wordpress.com/2010/10/msft_logo.jpg" /> 
     </Button> 
    </StackPanel> 
</Window> 

编辑:修正闪烁的问题。只需要将Popup放置在底部和中间位置即可。

+0

我设置ClipToBounds = True来解决闪烁问题。 – 2013-01-08 14:58:23

回答

2

我最终不得不写一个转换器,它根据弹出窗口的高度和放置目标将其下移。

使用这样的multibinding的信息传递到我的转换器VerticalOffset:

<MultiBinding Converter="{StaticResource PopupVerticalAligner}"> 
    <Binding RelativeSource="{RelativeSource Self}" Path="PlacementTarget.ActualHeight" /> 
    <Binding RelativeSource="{RelativeSource Self}" Path="ActualHeight" /> 
</MultiBinding> 
+0

您能否为转换器添加代码? – 2012-10-03 09:39:07

+0

看看这个问题......它可能会更有意义底部对齐和传递宽度来计算居中,但它取决于你:http://stackoverflow.com/questions/10972335/how-to-位置工具提示底部中央 – sohum 2012-10-03 19:39:25

0

您是否尝试过MouseEnter事件?然后,您可以打开DispatcherTimer上的弹出窗口,然后再关闭它。

+0

如果可以,我想避免代码隐藏。 – sohum 2012-08-06 20:31:05

+0

好:)。您可以使用MVVM-Light和RelayCommands来调用视图模型中的弹出窗口。从那里使用子窗口服务或类似的东西来处理窗口逻辑。 – LueTm 2012-08-06 20:32:20

+0

我真的不想添加一个依赖到另一个工具包只是为了让一个标签显示在正确的位置和方式。上面的代码几乎可以工作。我觉得我的触发器只是在错误的对象上,而我错过了关于如何使用Popup的展示位置属性的技巧。 – sohum 2012-08-06 20:41:58

0

添加到sohum的answer,这里就是我得到了下一个切换按钮我的ListView-弹出底部居中。它根据列表视图的宽度而正确地偏移。我还留下了一些切换按钮的直观行为,比如再次点击togglebutton来隐藏弹出窗口。

<ToggleButton x:Name="ParentToggleButton" IsChecked="{Binding ToggleButtonStatus}" IsHitTestVisible="{Binding ElementName=ToggledPopup, Path=IsOpen, Converter={StaticResource BoolToInvertedBoolConverter}}" > 
    <ToggleButton.Content>...</ToggleButton.Content> 
</ToggleButton> 
<Popup PlacementTarget="{Binding ElementName=ParentToggleButton}" Placement="Bottom" StaysOpen="False" IsOpen="{Binding ToggleButtonStatus}" x:Name="ToggledPopup"> 
    <Popup.HorizontalOffset> 
    <MultiBinding Converter="{StaticResource CenterToolTipConverter}"> 
     <Binding RelativeSource="{RelativeSource Self}" Path="PlacementTarget.ActualWidth"/> 
     <Binding ElementName="INeedYourWidth" Path="ActualWidth"/> 
    </MultiBinding> 
    </Popup.HorizontalOffset> 
    <ListView x:Name="INeedYourWidth" ItemsSource="{Binding ItemsSource}" > 
    <ListView.ItemTemplate> 
     <DataTemplate>...</DataTemplate> 
    </ListView.ItemTemplate> 
    </ListView> 
</Popup> 

BoolToInvertedBoolConverter返回true,如果假和假,如果真(允许当用户试图untoggle它弹出崩溃),并CenterToolTipConverter可以sohum的link被发现。

0

好多是把你的PlacementTarget控制Grid里面,让你Popup控制相同Grid的孩子,同时保持Placement=Bottom。这会在PlacementTarget控件下方显示以你为中心的Popup。没有转换器,没有样式,简单的简单XAML。