DataGrid选择整列

时间:2012-01-30 14:05:42

标签: c# wpf datagrid

我正在使用WPF DataGrid,我想允许用户通过单击列标题来选择整个列。我目前将SelectionUnit设置为CellOrRowHeader,因为我希望行具有相同的功能(效果很好)。是否有一种简单的方法可以通过单击列标题来选择列?

3 个答案:

答案 0 :(得分:2)

你有很多选择。一个是为DataGrid的标题样式创建自己的模板。在DataTemplate标记内,您可以更改标题的模板。 (您可以使用TextBlock或任何您想要的任何内容替换Button。)

<DataGrid>
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="DataGridColumnHeader" >
            <Setter Property="Foreground" Value="Blue" />
            <Setter Property="ContentTemplate" >
                <Setter.Value>
                    <DataTemplate>
                        <Button Content={Binding Content}" MouseDown="mouseDownEventHandler">
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.ColumnHeaderStyle>
</DataGrid>

或者如果您使用DataGrid.Columns填充列,并且需要单独设置它们,则可以使用:

<DataGrid>
    <DataGrid.Columns>
        <DataGridTextColumn HeaderTemplate="{StaticResource MyTemplate1"/>
        <DataGridHyperlinkColumn HeaderTemplate="{StaticResource MyTemplate2"/>
    </DataGrid.Columns>
</DatGrid>

其中MyTemplate1和2应该先在控件的Resources中定义。


编辑:

根据this link的另一种方法是将一个PreviewMouseDown添加到DataGrid,然后查明是否在标题上发生了鼠标停止。

这是她的事件处理程序的简单版本:

DependencyObject dep = (DependencyObject)e.OriginalSource;
while ((dep != null) && !(dep is DataGridColumnHeader))
{
    dep = VisualTreeHelper.GetParent(dep);
}
if (dep == null) return;
if (dep is DataGridColumnHeader)
{
    MessageBox.Show(((DataGridColumnHeader)dep).Content.ToString());
}

答案 1 :(得分:1)

您还可以修改ColumnHeaderStyle

在XAML中:

<DataGrid>
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="DataGridColumnHeader">
            <EventSetter Event="Click" Handler="DataGridColumnHeader_OnClick"></EventSetter>
        </Style>
    </DataGrid.ColumnHeaderStyle>
</DataGrid>

在代码隐藏中:

private void DataGridColumnHeader_OnClick(object sender, RoutedEventArgs e)
{
    var columnHeader = sender as DataGridColumnHeader;
    if (columnHeader != null)
        {
        if (!Keyboard.IsKeyDown(Key.LeftCtrl))
        {
            dataGrid.SelectedCells.Clear();
        }

        foreach (var item in dataGrid.Items)
        {
            dataGrid.SelectedCells.Add(new DataGridCellInfo(item, columnHeader.Column));
        }
    }
}

答案 2 :(得分:0)

在WPF中,不直接支持列选择,因此,需要扩展现有的DataGrid并添加对列选择的自定义支持。 下面的代码将允许您用于选择标题点击列。 为使以下代码正常工作,需要进行以下设置。

Xaml代码:

<local:DataGridEx SelectionUnit="CellOrRowHeader" CanUserSortColumns="False"/>

C#代码:

public class DataGridEx : DataGrid
{
    /// <summary>
    /// Holds the column that is selected.
    /// </summary>
    public object SelectedColumn
    {
        get { return GetValue(SelectedColumnProperty); }
        set { SetValue(SelectedColumnProperty, value); }
    }

    // Using a DependencyProperty as the backing store for SelectedColumn.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SelectedColumnProperty =
        DependencyProperty.Register("SelectedColumn", typeof(object),
    typeof(DataGridEx), new PropertyMetadata(null));
    private T GetVisualParent<T>(DependencyObject child) where T : Visual
    {
        DependencyObject parent = VisualTreeHelper.GetParent(child);
        if (parent == null || parent is T)
        {
            return parent as T;
        }
        else
        {
            return GetVisualParent<T>(parent);
        }
    }
    protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
    {
        DataGridColumnHeader dataGridColumnHeader = GetVisualParent<DataGridColumnHeader>(e.OriginalSource as DependencyObject);
        if (dataGridColumnHeader == null)
        {
            return;
        }
        if (SelectedCells != null && SelectedCells.Count > 0)
        {
            UnselectAllCells();
            SelectedCells.Clear();
        }
        SelectedColumn = dataGridColumnHeader.Column;
        foreach (var item in this.Items)
        {
            this.SelectedCells.Add(new DataGridCellInfo(item, dataGridColumnHeader.Column));
        }
        base.OnPreviewMouseDown(e);
    }
}