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