我只想在我的DataGrid
的最左列显示行号,是否有相应的属性可以实现这个功能?
请注意,这不是我的表的主键。当列排序时,我不希望这些行号随着它们所在的行移动。我基本上只想要一个连续的计数器。甚至不需要表头。
我只想在我的DataGrid
的最左列显示行号,是否有相应的属性可以实现这个功能?
请注意,这不是我的表的主键。当列排序时,我不希望这些行号随着它们所在的行移动。我基本上只想要一个连续的计数器。甚至不需要表头。
一种方法是在DataGrid的LoadingRow事件中添加它们。
<DataGrid Name="DataGrid" LoadingRow="DataGrid_LoadingRow" ...
void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.Header = (e.Row.GetIndex()).ToString();
}
当从源列表添加或删除项目时,数字可能会在一段时间内失去同步。为了解决此问题,请参见以下链接:
WPF 4 DataGrid:将行号放入行标题中
可以像这样使用
<DataGrid ItemsSource="{Binding ...}"
behaviors:DataGridBehavior.DisplayRowNumber="True">
LoadingRow
也会在排序期间调用,从而使行号始终保持有序? - VoodooChilde.Row.Header = (e.Row.GetIndex() + 1).ToString();
翻译为: 如果您想从#1开始:e.Row.Header = (e.Row.GetIndex() + 1).ToString();
- JohnBHeadersVisibility
设置为All
或Row
。Columns
和None
将不会显示。例如:
<DataGrid HeaderVisibility="All"></DataGrid>
- p__d添加关于Fredrik Hedblad答案的简短信息。
<DataGrid Name="DataGrid" LoadingRow="DataGrid_LoadingRow" ...
void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.Header = (e.Row.GetIndex()+1).ToString();
}
...如果您想从1开始编号
<DataGrid ItemsSource="{Binding MyObservableCollection}" AlternationCount="{Binding MyObservableCollection.Count}" />
或者:
<DataGrid ItemsSource="{Binding MyObservableCollection}" AlternationCount="{Binding Items.Count, RelativeSource={RelativeSource Self}" />
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding AlternationIndex, RelativeSource={RelativeSource AncestorType=DataGridRow}}" />
</DataGrid.Columns>
这个问题比较老,但我想分享一些东西。我遇到了类似的问题,所需要的只是行头数字的简单枚举 RowHeader
,而Fredrik Hedblad的答案几乎已经解决了我的问题。
虽然这很好:
<DataGrid Name="DataGrid" LoadingRow="DataGrid_LoadingRow" ...
void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.Header = (e.Row.GetIndex()).ToString();
}
当删除和添加项目时,我的标题出现了问题。如果你有负责此操作的按钮,只需在“删除”代码下添加dataGrid.Items.Refresh();
,就像在我的情况下一样:
private void removeButton_Click(object sender, RoutedEventArgs e)
{
// delete items
dataGrid.Items.Refresh();
}
这对我解决了不同步的编号问题,因为刷新项会再次调用DataGrig_LoadingRow
。
补充一下关于这个问题的讨论...(我花了太多时间来找到这个答案!)
要避免行排序错误,您需要将数据网格的EnableRowVirtualization设置为False:
EnableRowVirtualization="False"
EnableRowVirtualization
属性被设置为 true
。当 EnableRowVirtualization
属性被设置为 true 时,DataGrid 不会为绑定数据源中的每个数据项实例化一个 DataGridRow
对象。相反,DataGrid 仅在需要时创建 DataGridRow 对象,并尽可能重复使用它们。MSDN 参考文档
RowHeaderStyle
测试后,最初的回答如下:
<DataGrid EnableRowVirtualization="false" ItemsSource="{Binding ResultView}" AlternationCount="{Binding ResultView.Count}" RowHeaderWidth="10">
<DataGrid.RowHeaderStyle>
<Style TargetType="{x:Type DataGridRowHeader}">
<Setter Property="Content" Value="{Binding Path=AlternationIndex, RelativeSource={RelativeSource AncestorType=DataGridRow}}" />
</Style>
</DataGrid.RowHeaderStyle>
</DataGrid>
这是为新手或急于解决问题的人提供几乎可以复制和粘贴的示例答案(不鼓励这样做),灵感来自@GrantA和@Johan Larsson在此帖子中的回答(以及其他许多回答该主题的人)。
You do not need to re-create your own Attached Property
<UserControl...
<Grid>
<DataGrid ItemsSource="{Binding MainData.ProjColl}"
AutoGenerateColumns="False"
AlternationCount="{ Binding MainData.ProjColl.Count}" >
<DataGrid.Columns>
<!--Columns given here for example-->
...
<DataGridTextColumn Header="Project Name"
Binding="{Binding CMProjectItemDirName}"
IsReadOnly="True"/>
...
<DataGridTextColumn Header="Sources Dir"
Binding="{Binding CMSourceDir.DirStr}"/>
...
</DataGrid.Columns>
<!--The problem of the day-->
<DataGrid.RowHeaderStyle>
<Style TargetType="{x:Type DataGridRowHeader}">
<Setter Property="Content"
Value="{Binding Path=(ItemsControl.AlternationIndex),
RelativeSource={RelativeSource AncestorType=DataGridRow}}"/>
</Style>
</DataGrid.RowHeaderStyle>
</DataGrid>
</Grid>
</UserControl>
using System.Windows;
using System.Windows.Controls;
public static class Index
{
private static readonly DependencyPropertyKey OfPropertyKey = DependencyProperty.RegisterAttachedReadOnly(
"Of",
typeof(int),
typeof(Index),
new PropertyMetadata(-1));
public static readonly DependencyProperty OfProperty = OfPropertyKey.DependencyProperty;
public static readonly DependencyProperty InProperty = DependencyProperty.RegisterAttached(
"In",
typeof(DataGrid),
typeof(Index),
new PropertyMetadata(default(DataGrid), OnInChanged));
public static void SetOf(this DataGridRow element, int value)
{
element.SetValue(OfPropertyKey, value);
}
public static int GetOf(this DataGridRow element)
{
return (int)element.GetValue(OfProperty);
}
public static void SetIn(this DataGridRow element, DataGrid value)
{
element.SetValue(InProperty, value);
}
public static DataGrid GetIn(this DataGridRow element)
{
return (DataGrid)element.GetValue(InProperty);
}
private static void OnInChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var row = (DataGridRow)d;
row.SetOf(row.GetIndex());
}
}
Xaml:
<DataGrid ItemsSource="{Binding Data}">
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="dataGrid2D:Index.In"
Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
</Style>
</DataGrid.RowStyle>
<DataGrid.RowHeaderStyle>
<Style TargetType="{x:Type DataGridRowHeader}">
<Setter Property="Content"
Value="{Binding Path=(dataGrid2D:Index.Of),
RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" />
</Style>
</DataGrid.RowHeaderStyle>
</DataGrid>