【问题标题】:WPF: Two DataGrids, same ItemsSource, One IsReadOnly, Bug?WPF:两个 DataGrid,相同的 ItemsSource,一个 IsReadOnly,Bug?
【发布时间】:2011-10-05 09:36:33
【问题描述】:

我有一个 WPF 应用程序,其中包含两个共享相同 ItemsSource 的 DataGrid。当我将 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;
        }
    }
}

【问题讨论】:

  • 您的意思是以编程方式添加记录吗(即通过 C# 如同在 MainWindow 构造函数中一样)?
  • 退出 IsReadOnly 模式的 DataGrid 通常有一个空白行,可用于添加记录。在这种情况下,此空白行不再可用。我没有尝试以编程方式添加记录。
  • 也许将dgB的数据绑定设置为单向?

标签: c# wpf xaml datagrid itemssource


【解决方案1】:

我认为正在发生的事情是 IsReadOnly 属性通过 persons 的 DefaultView 使 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);
}

【讨论】:

  • +1 帮助我了解发生了什么。但这并没有给我想要的功能。我希望第二个网格包含第一个网格所做的所有内容,并在第一个网格执行时进行更改。当我在第一个网格中编辑一个项目时,它在第二个网格中确实发生了变化。但不幸的是,在第一个网格中添加或删除记录不会影响第二个网格。
  • @Jeff:您是否将List 更改为ObservableCollection?我刚试过这个,它适用于编辑单元格和添加/删除行
  • 顺便说一下,排序顺序也受到影响...由于相同的集合视图使用,
猜你喜欢
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
  • 2014-10-05
  • 1970-01-01
  • 2013-04-21
  • 2013-06-30
  • 2017-10-23
  • 2012-10-30
相关资源
最近更新 更多