【问题标题】:Getting a GridView to select the row on click (not just clicking on the text)获取 GridView 以在单击时选择行(不仅仅是单击文本)
【发布时间】:2010-08-03 09:54:11
【问题描述】:

我们想在该行的任意位置单击鼠标来选择一行。目前用户必须单击行中的文本才能选择行。

这是我们在 Grid 中的 ListView,里面有一个 GridView:

<ListView  Grid.Row="1"
           x:Name="lvUsers"
           PreviewMouseDoubleClick="lvUsers_PreviewMouseDoubleClick"
           IsSynchronizedWithCurrentItem="True"
           ItemsSource="{Binding AllUsers,Mode=TwoWay}"
           ScrollViewer.VerticalScrollBarVisibility="Auto"
           ScrollViewer.HorizontalScrollBarVisibility="Disabled">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Username"
                                Width="150"
                                DisplayMemberBinding="{Binding UserDTO.Name}" />
                <GridViewColumn Header="Fullname"
                                Width="150"
                                DisplayMemberBinding="{Binding UserDTO.FullName}" />
                <GridViewColumn Header="Roles"
                                Width="250"
                                DisplayMemberBinding="{Binding Roles}" />
                <GridViewColumn Header="Default station"
                                Width="200" DisplayMemberBinding="{Binding UserDTO.DefaultStation.StationName}"/>
            </GridView>
        </ListView.View>
    </ListView>

当用户单击行中的任意位置(即使是在 FullName 和 Roles 之间的空白处)时,我们如何让它选择该行?

谢谢!

【问题讨论】:

  • 您找到解决方案了吗?
  • 对不起,我没有。我们的产品仍然有这个“bug”。

标签: wpf gridview listview wpf-controls selection


【解决方案1】:

我怀疑您没有得到答案,因为没有人可以复制问题。实际上,仅使用您提供的代码,您就可以单击网格中的任何位置,然后将选择该项目。

我猜您团队中的某个人已将 ListViewItem 模板化为您可能知道也可能不知道的样式。如果您模板 ListViewItem 那么您可以看到您正在谈论的问题。

如果你运行下面的代码,你会发现问题:

<Grid>
        <ListView  Grid.Row="1"
           x:Name="lvUsers"
           IsSynchronizedWithCurrentItem="True"
           ItemsSource="{Binding AllUsers,Mode=TwoWay}"
           ScrollViewer.VerticalScrollBarVisibility="Auto"
           ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListViewItem">
                                <Grid>
                                    <Rectangle x:Name="ItemBackground" Fill="{x:Null}"/>
                                    <GridViewRowPresenter/>
                                </Grid>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter TargetName="ItemBackground" Property="Fill" Value="LightGray" />
                                    </Trigger>
                                    <Trigger Property="IsSelected" Value="True">
                                        <Setter TargetName="ItemBackground" Property="Fill" Value="Gray" />
                                        <Setter TargetName="ItemBackground" Property="StrokeDashArray" Value="1 1 1"/>
                                        <Setter TargetName="ItemBackground" Property="Stroke" Value="DarkGray"/>
                                        <Setter TargetName="ItemBackground" Property="StrokeThickness" Value="1"/>
                                        <Setter TargetName="ItemBackground" Property="RenderOptions.EdgeMode" Value="Aliased"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.Items>
                <ListViewItem Content="Test Item 1"></ListViewItem>
                <ListViewItem Content="Test Item 2"></ListViewItem>
                <ListViewItem Content="Test Item 3"></ListViewItem>
                <ListViewItem Content="Test Item 4"></ListViewItem>
            </ListView.Items>
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="150" DisplayMemberBinding="{Binding}"/>
                    <GridViewColumn Width="150" DisplayMemberBinding="{Binding}"/>
                    <GridViewColumn Width="150" DisplayMemberBinding="{Binding}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>

在这种情况下,单击空白区域会显示问题行为。它不会触发列表项的选择。

解决方法是在整个item模板上添加一个透明度为0的矩形,像这样:

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="ListViewItem">
            <Grid>
                <Rectangle x:Name="ItemBackground" Fill="{x:Null}"/>
                <GridViewRowPresenter/>
                **<Rectangle Fill="White" Opacity="0"></Rectangle>**
            </Grid>
        < etc... >

现在点击有效,悬停也有效。

我希望这会有所帮助。它也让我们发疯,直到我们想到它。

【讨论】:

    【解决方案2】:

    Nigel Shaws 答案的附录,它为我提供了这个问题的答案。

    您无需将Rectangle 放在整个Template 上。这将阻止您在行中可能拥有的任何控件。相反,您可以简单地在GridViewRowPresenter 后面使用Rectangle。只需确保设置了 RectangleFill 属性即可。

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListViewItem">
                <Grid>
                    <Rectangle x:Name="ItemBackground" Fill="White" Opacity="0"/>
                    <GridViewRowPresenter/>
                </Grid>
            < etc... >
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-22
      • 1970-01-01
      • 2018-01-29
      • 1970-01-01
      • 1970-01-01
      • 2013-07-01
      • 2023-03-17
      • 1970-01-01
      相关资源
      最近更新 更多