ReadWrite& ReadOnly datagrid绑定到共享源,导致ReadWrite不正确ReadWrite?

时间:2012-12-10 19:53:00

标签: wpf binding wpfdatagrid readonly-attribute

我发现了一些奇怪的事: 我有一个带有两个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; }
}

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

1 个答案:

答案 0 :(得分:2)

一个很好的问题约翰!我的猜测是,因为你没有明确地提供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:在真假的更多组合之后,我注意到的唯一一致的事情是,如果IsReadOnly中的最后DataGrid设置为True,则所有其他DataGrids变得只读。但如果最后一个设置为false,则所有其他DataGrids都根据自己的IsReadOnly设置运行。这个问题可能是由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.