为什么 WPF 的 DataGrid 在使用相同的代码重新初始化时表现不同?

问题描述 投票:0回答:1

我有一个

UserControl
,其中包含以下 Xaml,代表一个简单的
DataGrid
,带有用于测试的按钮:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <DataGrid x:Name="TestGrid" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Id" Binding="{Binding Path=Id}"/>
            <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}"/>
        </DataGrid.Columns>
    </DataGrid>

    <StackPanel  Grid.Row="1"  Orientation="Horizontal">
        <Button  Content="Init View" Click="InitViewButton_Click"/>
        <Button  Content="Add" Click="AddButton_Click"/>
        <Button  Content="Change Ids" Click="ChangeIdButton_Click"/>
        <Button  Content="Filter X" Click="FilterButton_Click"/>
    </StackPanel>
</Grid>

以及(在代码隐藏中)以下代码:

public ListCollectionView TestView {get; set;}

public ObservableCollection<TestItem> TestItems {get; set;} 

private void init()
{
    var result = new ObservableCollection<TestItem>()
    {
        new TestItem() { Id = 1, Name = "First A" },
        new TestItem() { Id = 2, Name = "Second A" },
        new TestItem() { Id = 3, Name = "Third A" },

    };

    TestItems = result;

    var view = new ListCollectionView(TestItems);
    view.SortDescriptions.Add(new SortDescription(nameof(TestItem.Id), ListSortDirection.Descending));
    view.IsLiveSorting = true;
    view.Filter = o => (o as TestItem)?.Name.Contains("A") ?? false;
    TestView = view;
}

private void InitViewButton_Click(object sender, RoutedEventArgs e)
{
    init();
    TestGrid.ItemsSource = TestView;
    TestGrid.Items.Refresh();
}

private void AddButton_Click(object sender, RoutedEventArgs e)
{
    var item = new TestItem() { Id = 99, Name = "New AX" };

    TestItems.Add(item);
}

private void ChangeIdButton_Click(object sender, RoutedEventArgs e)
{
    foreach (var testItem in TestItems)
    {
        testItem.Id = Random.Shared.Next(1000);
    }
}

private void FilterButton_Click(object sender, RoutedEventArgs e)
{
    TestView.Filter = o => (o as TestItem)?.Name.Contains("X") ?? false;
}

单击“Init View”后,

DataGrid
按预期填充,其他按钮按预期工作,例如更改 Id 时,会对行进行重新排列。

如果我再次单击“Init View”,则一切正常,除了重新排序,即更改 Id 不会重新排序行 - 不过,显示的项目已正确更新。

怎么会这样?

旁注:尽管没有设置

IsLiveFiltering
,过滤仍按预期工作,例如如果我从名称中删除“A”,则该项目将从
DataGrid
中删除。

c# xaml binding datagrid
1个回答
0
投票

在将 DataGrid ItemsSource 设置为新的 ListCollectionView 后(第一次之后),SortDescriptions 似乎以某种方式被清除。

如果您在 TestGrid.ItemsSource = TestView 之后添加 SortDescription,则它可以工作。

private void init()
{
    var result = new ObservableCollection<TestItem>()
    {
        new TestItem() { Id = 1, Name = "First A" },
        new TestItem() { Id = 2, Name = "Second A" },
        new TestItem() { Id = 3, Name = "Third A" },
    };

    TestItems = result;

    var view = new ListCollectionView(TestItems);

    view.IsLiveSorting = true;
    view.Filter = o => (o as TestItem)?.Name.Contains("A") ?? false;
    TestView = view;
}

private void InitViewButton_Click(object sender, RoutedEventArgs e)
{
    init();
    TestGrid.ItemsSource = TestView;
    TestView.SortDescriptions.Add(new SortDescription(nameof(TestItem.Id), ListSortDirection.Descending));
    //TestGrid.Items.Refresh();
}
© www.soinside.com 2019 - 2024. All rights reserved.