【问题标题】:clicking the hyperlink inside WPF listview is not selecting the corresponding row单击 WPF 列表视图中的超链接未选择相应的行
【发布时间】:2013-05-17 17:12:14
【问题描述】:

我有以下列表视图,其中包含一个 gridview 列和该 gridview 列的单元格模板。但是当我点击“超链接”时,相应的gridview行没有被选中。

谁能给我一个解决办法

数据模板

<DataTemplate x:Key="smTemplate">
     <StackPanel>
        <TextBlock TextWrapping="Wrap" Text="{Binding SM}" />
        <TextBlock>
            <Hyperlink x:Name="tHLink" Click="thL_Click"      KeyboardNavigation.IsTabStop="True">
                <TextBlock Text="TH" />
            </Hyperlink>
                    </TextBlock>                   
     </StackPanel>
</DataTemplate>            

列表视图

 <ListView Focusable="True">                
    <ListView.View>
       <GridView>
          <GridViewColumn Header="DM" CellTemplate="{StaticResource smTemplate}" />
       </GridView>
    </ListView.View>
    </ListView>

【问题讨论】:

  • 您的 thL_Click 处理程序中有什么?
  • 我正在使用该处理程序来设置另一个控件的可见性。
  • 也许尝试在您的 thl_Click 中设置 e.Handled = false .. 我认为您的处理程序可能会“吃掉”鼠标点击。或者也许在 StackPanel 上将 IsHitTestVisible 设置为 false。
  • 我试过这些......但没有运气:(
  • 嘿有解决办法..

标签: wpf listview hyperlink selection


【解决方案1】:

尝试更改ListViewItem 样式,以便在获得键盘焦点时自动选择它:

<ListView>
   <!-- ..... -->
   <ListView.ItemContainerStyle>
       <Style TargetType="{x:Type ListViewItem}">
           <Style.Triggers>
               <EventTrigger RoutedEvent="PreviewGotKeyboardFocus">
                   <BeginStoryboard>
                       <Storyboard>
                           <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsSelected">
                               <DiscreteBooleanKeyFrame Value="True" KeyTime="0:0:0" />
                           </BooleanAnimationUsingKeyFrames>
                       </Storyboard>
                   </BeginStoryboard>
               </EventTrigger>
           </Style.Triggers>
       </Style>
   </ListView.ItemContainerStyle>
</ListView>

【讨论】:

    【解决方案2】:

    Hyperlink 覆盖 OnMouseLeftButtonDownOnMouseLeftButtonUp。在这些方法中,e.Handled = true 在处理您的事件处理程序之后设置,因此您不能通过将事件附加到 XAML 中的控件来覆盖它。为了修复行为以满足您的需要,您需要创建一个派生自 Hyperlink 的类并覆盖鼠标处理事件。

    然而,这一切都是不必要的。从您的代码来看,Hyperlink 导致的问题多于它解决的问题,因此我建议将其替换为具有自定义样式的单个 TextBlock 控件。

    <TextBlock Text="TH" TextDecorations="Underline" Cursor="Hand"
               Foreground="{x:Static SystemColors.HotTrackBrush}"/>
    

    【讨论】:

      【解决方案3】:

      [不好回答]
      我找到了一个很好的解决方案here。我只是复制并粘贴了以下代码并使用了它。它的工作。即使你点击白色空白,也会选择相应的行。

                  <ControlTemplate TargetType="ListViewItem" x:Key="rowStyle1">
                      <Grid x:Name="backGroundPanel">
                          <GridViewRowPresenter Content="{TemplateBinding Content}" />
                          <Rectangle Fill="White" Opacity="0"/>
                      </Grid>
                      <ControlTemplate.Triggers>
                          <Trigger Property="IsSelected" Value="True">
                              <Setter TargetName="backGroundPanel" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                              <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                          </Trigger>
                      </ControlTemplate.Triggers>
                  </ControlTemplate>
                  <Style x:Key="columnHeaderContianerStyle" TargetType="ListViewItem">
                      <Setter Property="Template" Value="{StaticResource ResourceKey=rowStyle1}"/>
                  </Style>
      

      我设置了 listview 的属性“ItemContainerStyle”,如下面的代码:

      <ListView ItemContainerStyle="{DynamicResource columnHeaderContianerStyle}" ... >
      


      [修改后的答案]
      如果我们有兴趣在列控件中捕获鼠标,则上述解决方案不起作用。因为 backGroundPanel 中的矩形捕获鼠标事件,所以它会阻止 GridViewRowPresenter 捕获鼠标事件。所以我们必须使用具有 2 个特征的策略:

      1. 鼠标事件应由内栏控件捕获。
      2. 当用户单击行中的每个位置时,必须选择该行。

      所以,这次解决方案变得更简单了。我为我的 ListView 的 ItemContainerStyle 使用了下面的代码。

      <Style x:Key="columnHeaderContianerStyle" TargetType="ListViewItem">
      
                  <EventSetter Event="PreviewMouseDown" Handler="ListViewItem_PreviewMouseDown"></EventSetter>
              </Style>
      

      事件处理程序是:

      private void ListViewItem_PreviewMouseDown(object sender, MouseButtonEventArgs e)
          {
              if (sender is ListViewItem)
              {
                  ListViewItem s = (ListViewItem)sender;
                  s.IsSelected = true;
              }
          }
      

      它适用于提到的 2 个功能。

      【讨论】:

        猜你喜欢
        • 2011-08-08
        • 2012-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多