在WPF的DataGrid控件中,如果将列设置为其中一个默认列类型(如DataGridTextColumn或DataGridCheckBoxColumn),对该列进行排序,然后更改其值,网格将自动重新排序。
但是,如果使用DataGridTemplateColumn(并允许对列进行排序),则可以对其进行排序,但更改此列中单元格的值不会导致网格不会重新排序。 如何诱导它自动触发重新排序?
XAML:
<DataGrid Name="grid" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="First name" Binding="{Binding First}"/>
<DataGridTemplateColumn Header="Last name" SortMemberPath="Last">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Last}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
结合:
ObservableCollection items = new ObservableCollection();
grid.ItemsSource = items;
items.Add(new Character() { First = "Homer", Last = "Simpson" });
items.Add(new Character() { First = "Kent", Last = "Brockman" });
items.Add(new Character() { First = "Montgomery", Last = "Burns" });
这是我的项目类,以防相关:
public class Character : INotifyPropertyChanged {
private string first, last;
public event PropertyChangedEventHandler PropertyChanged;
private void Notify(string name) {
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
public string First { get { return first; } set { first = value; Notify("First"); } }
public string Last { get { return last; } set { last = value; Notify("Last"); } }
}
答案 0 :(得分:4)
我也在寻找答案。我找到了一个解决方案:(不满意,但......)
更新您的收藏后,您可以执行以下操作:
SortDescription sortDescription = grdData.Items.SortDescriptions[0];
grdData.ItemsSource = null;
grdData.ItemsSource = Data;
grdData.Items.SortDescriptions.Add(sortDescription);
丑陋但确实有效。您将要存储整个集合,而不像我的第一个项目那样。
它的一个问题是DataGrid丢失了指示排序的标题,因此尽管它正确地解析,但不再选择列标题,并且箭头显示排序方向。
答案 1 :(得分:4)
我知道这是旧的但我也得到了这个DataGridTemplateColumn重新排序问题。这不会发生在DataGridTextColumn上。我在列标题上使用完整排序方向修复的方式是:
// after updating the collection, remove all SortDescription and add'em back.
SortDescriptionCollection sortDescriptions = new SortDescriptionCollection();
foreach (SortDescription sd in dataGrid.Items.SortDescriptions)
{
sortDescriptions.Add(sd);
}
dataGrid.Items.SortDescriptions.Clear();
foreach (SortDescription sd in sortDescriptions)
{
dataGrid.Items.SortDescriptions.Add(sd);
}
希望这有助于人们。
答案 2 :(得分:1)
2016年这些答案都不适合我。
经过一番尝试和错误后,我想出了这个并且似乎工作得很好:
dataGrid.Items.IsLiveSorting = true;
答案 3 :(得分:0)
我在VS2010下的C#WPF中有一个DataGrid,无论XAML设置如何都不会排序。出于某种原因,这个隐藏的DataGrid(在辅助选项卡上)存在排序顺序问题,其中主DataGrid在类似设置下很好。因此,我必须以图形方式对DataGrid进行排序。以下是我的笔记:
首先是两个DataGrids的XAML(主要和次要,我们只会对第二个“扩展名称”网格进行排序:
<TabControl Grid.Row="1" Name="tabControl1" VerticalAlignment="Top" Style="{StaticResource Section}" Margin="3" Padding="0" FontFamily="Arial" FontSize="10" BorderThickness="0" >
<TabItem Name="tabCommon" Style="{StaticResource NameTab}">
<DataGrid Name="grdCommonNames" SelectionChanged="grdCommonNames_SelectionChanged" PreviewKeyDown="grdCommonNames_PreviewKeyDown" Style="{StaticResource NameListGrid}" Focusable="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name, NotifyOnTargetUpdated=True}" Width="SizeToCells" Header="Name" CellStyle="{StaticResource NameListCol}" SortDirection="Ascending" />
<DataGridTextColumn Binding="{Binding Pronunciation, NotifyOnTargetUpdated=True}" Width="SizeToCells" Header="Pronunciation" CellStyle="{StaticResource NameListRightCol}"/>
</DataGrid.Columns>
</DataGrid>
</TabItem>
<TabItem Name="tabExtended" Style="{StaticResource NameTab}">
<DataGrid Name="grdExtendedNames" SelectionChanged="grdCommonNames_SelectionChanged" PreviewKeyDown="grdCommonNames_PreviewKeyDown" Style="{StaticResource NameListGrid}" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name, NotifyOnTargetUpdated=True}" Width="SizeToCells" Header="Name" CellStyle="{StaticResource NameListCol}" SortDirection="Descending" SortMemberPath="Name"/>
<DataGridTextColumn Binding="{Binding Pronunciation, NotifyOnTargetUpdated=True}" Width="SizeToCells" Header="Pronunciation" CellStyle="{StaticResource NameListRightCol}"/>
</DataGrid.Columns>
</DataGrid>
</TabItem>
</TabControl>
然后,代码片段在点击后对第二个选项卡Datagrid进行排序。我们只是第一次排序,这就是布尔值在这里的原因。这样,如果他们手动对其他列进行排序,即使它们返回到第一个选项卡然后重新访问第二个选项卡,它也会被保留。
这里我们在Datagrid中的第一列名为“Name”。 On Click片段:
if (!extendSorted)
{
SortDescription extSort = new SortDescription("Name", ListSortDirection.Ascending);
grdExtendedNames.Items.SortDescriptions.Add(extSort);
extendSorted = true;
}
希望能帮助其他人通过代码对数据网格进行排序。我们发现的大多数其他示例都可以用于简单的设置,但是在这个双数据网格选项卡式设置中,它将排序排除在外。
答案 4 :(得分:0)
在向DataGrid中插入新行时,我遇到了类似的问题。 我通过刷新DataGrid的项来解决了这个问题。
dataGrid.Items.Refresh()。这还恢复了排序。
不要忘记在DataGridColumn上设置SortDirection(在这种情况下,它是一个DataGridTextColumn)
DataGrid定义:
<DataGrid x:Name="dgCustomers" ItemsSource="{Binding CustomerTable}" AutoGenerateColumns="False" CanUserDeleteRows="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Kunden ID" Binding="{Binding Path=KundenID,Mode=TwoWay}" SortDirection="Ascending" />
<DataGridTextColumn Header="Name" Binding="{Binding Path=Kundenname,Mode=TwoWay}"/>
</DataGrid.Columns>
</DataGrid>
CS档案:
private void btnSavecustomerChanges_Click(object sender, RoutedEventArgs e)
{
try
{
BL.UpdateCustomerChanges();
dgCustomers.Items.Refresh();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Fehler beim Speichern", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
答案 5 :(得分:0)
If DataGridMain.Items.SortDescriptions.Count > 0 Then
Dim vSortDescColl As New SortDescriptionCollection
For Each vSortDesc In DataGridMain.Items.SortDescriptions
vSortDescColl.Add(vSortDesc)
Next
DataGridMain.ItemsSource = Nothing
DataGridMain.ItemsSource = vCallColl
For Each vSortDesc In vSortDescColl
DataGridMain.Items.SortDescriptions.Add(vSortDesc)
For Each vColumn In DataGridMain.Columns
If vColumn.SortMemberPath = vSortDesc.PropertyName Then
vColumn.SortDirection = vSortDesc.Direction
Exit For
End If
Next
Next
End If