[英]WPF ListView column selection
我有一个ListView。 当我选择一行时,我希望只选择一个单元格而不是整个行。 我怎么能得到这个? 这是我的样式和模板。
<ListView x:Name="List"
ItemsSource="{Binding }"
ItemContainerStyle="{DynamicResource ListItemStyle}">
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridViewColumn HeaderContainerStyle="{StaticResource myHeaderStyle}"
Header="1"
CellTemplate="{StaticResource myCellTemplate1}">
</GridViewColumn>
<GridViewColumn Header="2"
HeaderContainerStyle="{StaticResource myHeaderStyle}"
HeaderTemplate="{StaticResource myHeaderTemplate}"
CellTemplate="{StaticResource cellTemplate2}">
</GridViewColumn>
<GridViewColumn Header="3"
HeaderContainerStyle="{StaticResource myHeaderStyle}"
HeaderTemplate="{StaticResource myHeaderTemplate}"
CellTemplate="{StaticResource cellTemplate3}" />
<GridViewColumn Header="4"
HeaderContainerStyle="{StaticResource myHeaderStyle}"
HeaderTemplate="{StaticResource myHeaderTemplate}"
CellTemplate="{StaticResource cellTemplate4}"/>
</GridView>
</ListView.View>
</ListView>
<Style x:Key="ListItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}" >
<Grid SnapsToDevicePixels="True" Margin="0" Width="410" x:Name="GridSmall">
<Border x:Name="Border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="0" />
<GridViewRowPresenter x:Name="Rows" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Yellow"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
<DataTemplate x:Key="myCellTemplate1">
<DataTemplate.Resources>
<local:NullIdConverter x:Key="NullIdConverterKey"/>
</DataTemplate.Resources>
<DockPanel x:Name="RR">
<TextBlock FontSize="18" x:Name="TxtBl"
HorizontalAlignment="Center"
Text="{Binding Path = Id}"/>
</DockPanel>
</DataTemplate>
谢谢。
如果您使用的是.NET 3.5 SP1或.NET 4,建议您查看DataGrid而不是ListView。
我认为它为您的数据提供了更大的灵活性,并且具有一个名为SelectionUnit的属性,您可以将其设置为“ Cell”,从而为您提供所需的功能。
不幸的是,我认为没有一种简单的方法可以对ListView进行相同操作。
好吧.....这并不容易。 就像Scott所说的那样,在.Net 4及其DataGrid控件中使用SelectionUnit和SelectionMode可能会使生活更轻松。 但是,如果您要像开始那样做,请尝试以下操作:
在XAML中(我并没有做为模板或样式来完成全部工作,仅一栏就可以使它起作用),您需要这样的代码:
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border Name="myOwnBorder" BorderBrush="Gray" BorderThickness="1,1,1,0" Margin="-6,0,-6,0">
<Grid Margin="6,0,6,0">
<TextBlock Text="{Binding}"/>
</Grid>
</Border>
</DataTemplate>
</GridViewColumn.CellTemplate>
...然后在代码行为中(不是很好的设计实践,但是为了演示起见)创建一个函数,例如:
static bool FindBorderInListView(DependencyObject dep, ListView listView,
out Border border, out ListViewItem lvItem)
{
border = null;
lvItem = null;
DependencyObject depObj = dep;
while (depObj != listView)
{
if (border == null && depObj is Border)
{
border = depObj as Border;
if (border.Name != "myOwnBorder")
{
border = null;
}
}
else if (depObj is ListViewItem)
{
lvItem = depObj as ListViewItem;
}
depObj = VisualTreeHelper.GetParent(depObj);
}
return border != null && lvItem != null;
}
然后从ListView的PreviewMouseDown事件中调用它:
private void MyList_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
Border border;
ListViewItem lvItem;
if (FindBorderInListView(e.OriginalSource as DependencyObject, this.MyList,
out border, out lvItem))
{
ItemContainerGenerator generator = this.MyList.ItemContainerGenerator;
int rowIndex = generator.IndexFromContainer(lvItem);
int columnIndex = Grid.GetColumn(border);
MessageBox.Show("Cell #:" + rowIndex + columnIndex);
}
}
应归功于应归功于何事,乔什·史密斯(Josh Smith)在回想MSDN社区问题的时候就想出了大约2007年的做法。
祝你好运! 我也不得不在DataGrid中实现类似的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.