我只想在DataGrid
的最左侧列中显示行号。是否有一些属性可以做到这一点?
请记住,这不是我桌子的主键。当列排序时,我不希望这些行号与它们的行一起移动。我基本上想要一个运行计数。它甚至不需要标题。
答案 0 :(得分:33)
一种方法是在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: Getting the Row Number into the RowHeader
可以这样使用
<DataGrid ItemsSource="{Binding ...}"
behaviors:DataGridBehavior.DisplayRowNumber="True">
答案 1 :(得分:9)
添加关于Fredrik Hedblad回答的简短信息。
<DataGrid Name="DataGrid" LoadingRow="DataGrid_LoadingRow" ...
void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.Header = (e.Row.GetIndex()+1).ToString();
}
...如果你想从1开始编号
答案 2 :(得分:6)
如果您的数据网格将其ItemsSource绑定到集合,请将数据网格的AlternationCount属性绑定到集合的count属性,或绑定到DataGrid的Items.Count属性,如下所示:
<DataGrid ItemsSource="{Binding MyObservableCollection}" AlternationCount="{Binding MyObservableCollection.Count}" />
或者:
<DataGrid ItemsSource="{Binding MyObservableCollection}" AlternationCount="{Binding Items.Count, RelativeSource={RelativeSource Self}" />
要么应该工作。
然后,假设您正在为最左侧的列使用DataGridTextColumn,请在DataGrid.Columns定义中执行以下操作:
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding AlternationIndex, RelativeSource={RelativeSource AncestorType=DataGridRow}}"
</DataGrid.Columns>
如果您不想从0开始,可以在绑定中添加转换器以增加索引。
答案 3 :(得分:4)
只是为了加上对此的讨论......(我花了太多时间发现它!)。
您需要在数据网格上将EnableRowVirtualization设置为False以防止行排序中的错误:
EnableRowVirtualization="False"
默认情况下,EnableRowVirtualization
属性设置为true
。当EnableRowVirtualization
属性设置为true时,DataGrid不会为绑定数据源中的每个数据项实例化DataGridRow
对象。相反,DataGrid仅在需要时才创建DataGridRow对象,并尽可能多地重用它们。 MSDN Reference here
答案 4 :(得分:2)
这是一个老问题,但我想分享一些东西。我有一个类似的问题,我需要的只是一个简单的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
。
答案 5 :(得分:2)
另一个答案是为新人或匆忙中的人提供几乎复制和粘贴的例子(不被鼓励),灵感来自@GrantA和@Johan Larsson(以及其他许多回答此问题的人的回答)关于该主题的众多帖子)
您无需重新创建自己的附加属性
<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>
答案 6 :(得分:0)
使用附加属性,完整来源here。
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>
答案 7 :(得分:0)
经过RowHeaderStyle
的测试后,NGI修复并扩展了样本:
<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>