让GridView在点击时选择行(而不仅仅是点击文本)

时间:2010-08-03 09:54:11

标签: 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之间的空白区域),我们如何让它选择行?

谢谢!

2 个答案:

答案 0 :(得分:4)

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

我猜你的团队中的某个人已经模仿了你可能知道或不知道的样式的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... >

现在点击工作,以及悬停。

我希望这会有所帮助。在我们想到它之前,它也让我们疯狂。

答案 1 :(得分:0)

Addendum to Nigel Shaws answer, which lead to an answer to this issue for me.

You don't need to put the Rectangle over the entire Template. This will block any controls you may have in your row. Instead you can simply use a Rectangle behind your GridViewRowPresenter. Just make sure the Fill property of the Rectangle is set.

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