单击WPF列表视图中的超链接不会选择相应的行

时间:2013-05-17 17:12:14

标签: wpf listview hyperlink selection

我有以下列表视图,其中包含该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>

3 个答案:

答案 0 :(得分: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>

答案 1 :(得分:0)

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

但是,这一切都是不必要的。根据您的代码判断,Hyperlink导致的问题多于解决的问题,因此我建议使用自定义样式的单个Hyperlink控件替换它。

TextBlock

答案 2 :(得分:0)

[不是一个好的答案]
我找到了一个很好的解决方案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捕获鼠标事件。所以我们必须使用具有两个特征的策略:

  1. 鼠标事件应由内部列控件捕获。
  2. 当用户点击行中的每个Where时,必须选择该行。
  3. 所以,这次解决方案变得更简单了。我使用下面的代码为我的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个提到的功能。