【问题标题】:Unable to show appropriate Popup message when mouse is over WPF Radio button鼠标悬停在 WPF 单选按钮上时无法显示适当的弹出消息
【发布时间】:2019-12-29 19:36:05
【问题描述】:

我有两个单选按钮(RadioButton1 和 RadioButton2)。 当鼠标悬停在其中一个单选按钮上时,我需要显示适当的弹出消息。因此我有以下要求

  • 要求 1:当鼠标悬停在“单选按钮 1”上时,弹出消息应为“单击单选按钮 1”。同样,当鼠标悬停在“Radio Button 2”上时,弹出消息应该是“Radio Button 2 is clicked”。

  • 要求 2:当鼠标在弹出窗口控件之外点击时,弹出窗口应该关闭。

  • 要求 3:弹出窗口还具有超链接,单击时会显示网页。因此,它应该保持打开状态。

为了满足上述要求,我使用了具有以下设置的 WPF 弹出控件

<Popup IsOpen="{Binding IsPopupOpen, Mode=TwoWay}" AllowsTransparency="True" PopupAnimation="Slide" StaysOpen="False" Placement="Bottom"  >
  <TextBlock  Text="{Binding RadioButtonContent, Mode=OneWay}" />

IsPopupOpen 和 RadioButtonContent 是 MVVM ViewModel 属性,当“MouseEnter”(使用的交互触发器)事件发生在一个单选按钮上时会更新。

但是我遇到了以下问题。

当鼠标从 Radio Button 1 移动时(此时弹窗打开到 Radio Button2,Popup 不显示“Radio Button 2 is clicked”。它仍然显示“Radio Button 1 is clicked”!!!。

在阅读MSDN 中的 Popup 文档后,我发现这是正确的行为,因为无论何时打开 pop,鼠标捕获都带有弹出内容(在本例中为 TextBlock)。因此,即使鼠标位于 Radiobutton 2 上,也不会触发 RadioButton2 的“MouseEnter”事件。

注意:我不能让 StaysOpen="True" 因为它不会关闭单击弹出父级外部。 (要求 2 失败) 我不能使用像“工具提示”或“装饰器”这样的控件,因为它不会留下来。 (要求 3 失败)

我怎样才能满足所有 3 个要求?

【问题讨论】:

  • 您必须使用Popup 并添加一个TextBlock,其中包含一个Hyperlink 作为其子元素。然后使用在RadioButton.MouseEnter 上触发的EventTrigger 并为Popup.IsOpen 属性设置动画以显示Popup
  • 嗨 BionicCode,谢谢。我做了那些事。但我的要求是当我将鼠标从单选按钮 1 移动到单选按钮 2 时,我应该弹出单选按钮 2。这不会发生,因为当鼠标悬停在单选按钮 1 上时,弹出内容显示为“单选按钮1 被点击”。弹出窗口保持打开状态并具有鼠标捕获功能。因此,当鼠标悬停在“单选按钮 2”上时,不会触发单选按钮的鼠标输入(因为鼠标捕获仍然带有弹出内容!!!)
  • 如果您可以包含一两张图片,可能还有一些有用的 XAML 代码
  • IsPopupOpen 和 RadioButtonContent 是 MVVM ViewModel 属性,当“MouseEnter”(使用的交互触发器)事件发生在一个单选按钮上时更新。
  • 因此,创建两个Popup 元素(每个RadioButton 一个)。在RadioButton.MouseEnter 上,始终通过将Popup.IsOpen 动画化为False 来关闭其他弹出窗口。在同一动画时间线上显示当前的Popup。这样他们就会表现得互斥。

标签: c# wpf


【解决方案1】:

关键是将Popup.StaysOpen属性设置为True(这是默认值)。现在Popup 不会自动关闭,您必须手动完成。要实现默认行为(单击窗口中某处时Popup 关闭),您应该添加所需的EventTrigger 并在Window 级别(或适当的焦点范围)处理例如FrameworkElement.PreviewMouseUp

以下示例显示RadioButton 引发FrameworkElement.MouseEnter 事件时的Popup。每个RadioButton 都有一个专用的Popup。在此Popup 显示之前,所有其他Popup 工具提示均已关闭。一旦Popup 或任何其他控件(关于EventTrigger 的范围)引发FrameworkElement.PreviewMouseUp 事件,打开的Popup 将被关闭。使用此配置,Popup 只允许接收一次单击(例如 Button)。
为了让Popup 在子元素收到鼠标点击时保持打开状态,您可以使用专用的EventTrigger 处理Popup.PreviewMouseUp 事件,将Popup.IsOpen 设置为True(以覆盖Popup 关闭@987654347 @)。对于更复杂的行为,我建议实现附加行为。

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        x:Name="Window"
        Width="800"
        Height="600">

  <StackPanel>
    <Popup x:Name="ToolTip1"
           StaysOpen="True"
           PlacementTarget="{Binding ElementName=RadioButton1}">
      <Border Background="Transparent">
        <StackPanel>
          <TextBlock Text="Click to navigate to external content1" />
          <Button Content="Link" 
                  Command="{Binding NavigateToUrlCommand}"
                  CommandParameter="https://stackoverflow.com" />
        </StackPanel>
      </Border>
    </Popup>
    <Popup x:Name="ToolTip2"
           StaysOpen="True"
           PlacementTarget="{Binding ElementName=RadioButton2}">
      <Border Background="Transparent">
        <StackPanel>
          <TextBlock Text="Click to navigate to external content2" />
          <Button Content="Link" 
                  Command="{Binding NavigateToUrlCommand}"
                  CommandParameter="https://stackoverflow.com" />
        </StackPanel>
      </Border>
    </Popup>
    <RadioButton x:Name="RadioButton1" />
    <RadioButton x:Name="RadioButton2" />
  </StackPanel>

  <Window.Triggers>
    <EventTrigger SourceName="Window"
                  RoutedEvent="FrameworkElement.PreviewMouseUp">
      <BeginStoryboard>
        <Storyboard>
          <BooleanAnimationUsingKeyFrames Storyboard.TargetName="ToolTip1"
                                          Storyboard.TargetProperty="IsOpen">
            <DiscreteBooleanKeyFrame KeyTime="0:0:0"
                                     Value="False" />
          </BooleanAnimationUsingKeyFrames>
          <BooleanAnimationUsingKeyFrames Storyboard.TargetName="ToolTip2"
                                          Storyboard.TargetProperty="IsOpen">
            <DiscreteBooleanKeyFrame KeyTime="0:0:0"
                                     Value="False" />
          </BooleanAnimationUsingKeyFrames>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>

    <EventTrigger SourceName="RadioButton1"
                  RoutedEvent="FrameworkElement.MouseEnter">
      <BeginStoryboard>
        <Storyboard>
          <BooleanAnimationUsingKeyFrames Storyboard.TargetName="ToolTip1"
                                          Storyboard.TargetProperty="IsOpen">
            <DiscreteBooleanKeyFrame KeyTime="0:0:0"
                                     Value="True" />
          </BooleanAnimationUsingKeyFrames>
          <BooleanAnimationUsingKeyFrames Storyboard.TargetName="ToolTip2"
                                          Storyboard.TargetProperty="IsOpen">
            <DiscreteBooleanKeyFrame KeyTime="0:0:0"
                                     Value="False" />
          </BooleanAnimationUsingKeyFrames>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
    <EventTrigger SourceName="RadioButton2"
                  RoutedEvent="FrameworkElement.MouseEnter">
      <BeginStoryboard>
        <Storyboard>
          <BooleanAnimationUsingKeyFrames Storyboard.TargetName="ToolTip2"
                                          Storyboard.TargetProperty="IsOpen">
            <DiscreteBooleanKeyFrame KeyTime="0:0:0"
                                     Value="True" />
          </BooleanAnimationUsingKeyFrames>
          <BooleanAnimationUsingKeyFrames Storyboard.TargetName="ToolTip1"
                                          Storyboard.TargetProperty="IsOpen">
            <DiscreteBooleanKeyFrame KeyTime="0:0:0"
                                     Value="False" />
          </BooleanAnimationUsingKeyFrames>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Window.Triggers>
</Window>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-29
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 2022-08-06
    相关资源
    最近更新 更多