Getting a GridView to select the row on click (not just clicking on the text)
We want to select a row on a mouseclick anywhere in that row. Currently the user has to click the text in the row to select the row.
This is our ListView inside a Grid, with a GridView inside it:
<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.开发者_JAVA百科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>
How can we get it to select the row when the user clicks anywhere in the row (even on the empty space between say the FullName and the Roles)?
Thanks!
I suspect you're not getting an answer because nobody can duplicate the problem. With just the code you've supplied in fact you can click anywhere in the grid and the item will be selected.
I'm guessing that someone on your team has templated the ListViewItem in a style that you may or may not know about. If you template ListViewItem then you can see the problem that you're talking about.
If you run the code below you'll see the problem:
<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>
In this case, clicking in the white space exhibits the problem behaviour. It doesn't trigger selection of the list item.
The solution is to add a rectangle with transparency 0 over the entire item template, like this:
<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... >
Now the click works, and the hover as well.
I hope this helps. It drove us crazy too until we thought of it.
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... >
精彩评论