wpf - 获取 GridView 以在单击时选择行(不仅仅是单击文本)

标签 wpf gridview listview wpf-controls selection

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

这是我们在 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 之间的空白处)时,我们如何让它选择行?

谢谢!

最佳答案

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

我猜您团队中的某个人已经以您可能知道也可能不知道的样式对 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>

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

解决方案是在整个项目模板上添加一个透明度为 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... >

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

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

关于wpf - 获取 GridView 以在单击时选择行(不仅仅是单击文本),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3395376/

相关文章:

wpf - WPF 列表框中的数据虚拟化

c# - WPF 将 slider 和文本框值绑定(bind)到静态 int 值

asp.net - gridview 显示文本而不是值

java - Android GridView 适配器与 AsyncTask

java - JavaFX ListView 控件的项目更改事件

wpf - 在 VS2013 的设计时显式设置/忽略可见性?

c# - 将组合框绑定(bind)到模型/ View 模型

c# - 从 GridViewRow ASP.NET 获取项目

java - Jface:如何强制Listviewer调整大小

jquery - 动态添加列表项到 j-Query Mobile ListView