繁体   English   中英

WPF ListView列选择

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM