wpf – ReadWrite和ReadOnly数据网格绑定到共享源,导致ReadWrite不正确ReadWrite?

我发现了一些奇怪的事

我有一个带有两个datagrids的表单,它绑定到同一个集合.

根据Xaml中datagrids的顺序,行为是不同的.

这按预期工作(添加的额外行存在):

<DockPanel>
    <DockPanel DockPanel.Dock="Right">
        <Label Content="ReadOnlyView" DockPanel.Dock="Top"/>
        <DataGrid ItemsSource="{Binding Persons}" IsReadOnly="True" />
    </DockPanel>
    <DockPanel>
        <Label Content="EditorView" DockPanel.Dock="Top" />
        <DataGrid ItemsSource="{Binding Persons}" IsReadOnly="False" CanUserAddRows="True" />
    </DockPanel>
</DockPanel>

以这种方式排列xaml让我困惑(没有额外的行添加)

<DockPanel>
    <DockPanel>
        <Label Content="EditorView" DockPanel.Dock="Top" />
        <DataGrid ItemsSource="{Binding Persons}" IsReadOnly="False" CanUserAddRows="True" />
    </DockPanel>
    <DockPanel DockPanel.Dock="Right">
        <Label Content="ReadOnlyView" DockPanel.Dock="Top"/>
        <DataGrid ItemsSource="{Binding Persons}" IsReadOnly="True" />
    </DockPanel>
</DockPanel>

下面是我用于此的虚拟ViewModel:

public class PersonsViewModel
{
    public PersonsViewModel()
    {
        Persons = new ObservableCollection<Person>
                    {
                        new Person {Name = "Johan"},
                        new Person {Name = "Dave"},
                    };
    }

    public ObservableCollection<Person> Persons { get; private set; }
}

public class Person
{
    public string Name { get; set; }
}

我的问题是这种行为的原因是什么?

最佳答案 一个很好的问题约翰!我的猜测是,因为你没有明确地为它提供CollectionViewSource,所以当你引用相同的源时,DataGrid自动生成的cvs在两者之间共享.

因此,当您发出两个IsReadOnly分配并成为共享源时,最后一个设置会获胜,两个DataGrid都会显示相同的效果.

为了确认我的猜测,我已经使用了这个代码,并且DataGrids的行为正如您为它们提供明确的CollectionViewSource时所期望的那样.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <CollectionViewSource Source="{Binding Persons}" x:Key="cvs1" />
        <CollectionViewSource Source="{Binding Persons}" x:Key="cvs2" />
    </Window.Resources>
    <DockPanel>
        <DataGrid ItemsSource="{Binding Source={StaticResource ResourceKey=cvs1}}" IsReadOnly="False" CanUserAddRows="True" />
        <DataGrid ItemsSource="{Binding Source={StaticResource ResourceKey=cvs2}}" IsReadOnly="True" />
    </DockPanel>
</Window>

编辑:进一步测试表明行为只能被描述为奇怪!我无法解释为什么会产生三个只读DG

<DataGrid ItemsSource="{Binding Persons}" IsReadOnly="True" />
<DataGrid ItemsSource="{Binding Persons}" IsReadOnly="False" />
<DataGrid ItemsSource="{Binding Persons}" IsReadOnly="True" />

但这会生成交替的只读和可编辑DG:

<DataGrid ItemsSource="{Binding Persons}" IsReadOnly="True" />
<DataGrid ItemsSource="{Binding Persons}" IsReadOnly="False" />
<DataGrid ItemsSource="{Binding Persons}" IsReadOnly="True" />
<DataGrid ItemsSource="{Binding Persons}" IsReadOnly="False" />

所以我想上面的CVS最好被描述为这种奇怪行为的解决方法,所以你可以实现你真正想要的.

编辑2:在更多真假的组合之后,我注意到的唯一一致的事情是,如果DataGrid中的Last IsReadOnly设置为True,则所有其他DataGrids变为只读.但如果最后一个设置为false,则所有其他DataGrids都根据自己的IsReadOnly设置运行.这个behvaiour可能是由于这个MSDN bit

If a conflict exists between the settings at the DataGrid, column,
or cell levels, a value of true takes precedence over a value of false.
点赞