WPF:两个datagrid,同一个ItemsSource,一个IsReadOnly, Bug

本文关键字:一个 IsReadOnly Bug ItemsSource 同一个 两个 datagrid WPF | 更新日期: 2023-09-27 18:02:00

我有一个WPF应用程序,其中两个datagrid共享相同的ItemsSource。当我将其中一个DataGrid的IsReadOnly属性设置为true时,我就失去了向另一个DataGrid添加记录的能力。我仍然可以编辑第二个数据网格的内容,但不能添加记录。

这是有意的吗?有别的办法吗?我可以为DataGrid使用IsEnabled="False",但这样我就失去了在其中滚动的能力。

设置如下:

XAML:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <DataGrid Name="dgA" Grid.Row="0" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="FirstName" Binding="{Binding Path=FirstName}" />
            <DataGridTextColumn Header="LastName" Binding="{Binding Path=LastName}" />
        </DataGrid.Columns>         
    </DataGrid>
    <DataGrid Name="dgB" Grid.Row="1" AutoGenerateColumns="False" IsReadOnly="True">
        <DataGrid.Columns>
            <DataGridTextColumn Header="FirstName" Binding="{Binding Path=FirstName}" />
            <DataGridTextColumn Header="LastName" Binding="{Binding Path=LastName}" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>
c#:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        List<Person> persons = new List<Person>();
        persons.Add(new Person() { FirstName = "Bob", LastName = "Johnson" });
        persons.Add(new Person() { FirstName = "John", LastName = "Smith" });
        dgA.ItemsSource = persons;
        dgB.ItemsSource = persons;
    }
    class Person
    {
        public Person() { }
        public string FirstName
        {
            get;
            set;
        }
        public string LastName
        {
            get;
            set;
        }
    }
}

WPF:两个datagrid,同一个ItemsSource,一个IsReadOnly, Bug

我认为发生的事情是,IsReadOnly属性通过DefaultView为persons使DataGrid只读,并且由于此DefaultView对于您的两个DataGrid's都是相同的,因此都失去了添加新行的能力。

两者都没有变成只读然而(正如你在你的问题中所说),所以我不确定这是一个错误还是一个期望的行为。

我也不确定在幕后发生了什么,这里导致这种行为,但你可以通过调试器验证CollectionView的是相同的(因为CollectionView属性是私有的)。以下三个语句为真

dgA.Items.CollectionView == CollectionViewSource.GetDefaultView(persons) // true
dgB.Items.CollectionView == CollectionViewSource.GetDefaultView(persons) // true
dgA.Items.CollectionView == dgB.Items.CollectionView // true

您可以通过将List更改为ObservableCollection并为DataGrid's使用单独的ListViewCollection's来获得它的工作方式

public MainWindow()
{
    InitializeComponent();
    ObservableCollection<Person> persons = new ObservableCollection<Person>();
    persons.Add(new Person() { FirstName = "Bob", LastName = "Johnson" });
    persons.Add(new Person() { FirstName = "John", LastName = "Smith" });
    dgA.ItemsSource = new ListCollectionView(persons);
    dgB.ItemsSource = new ListCollectionView(persons);
}
相关文章: