WPF Microsoft DataGrid具有奇怪的“IsReadOnly”行为。为什么?

时间:2018-05-01 13:46:40

标签: c# wpf datagrid behavior readonly-attribute

只使用一个DataGrid就可以了。

但是在我的示例代码中,我定义了一个复选框(窗口的左上角)来切换ListView项目中DataGrids的ReadOnly属性的状态。 ListView DataGrids的ReadOnly状态正在发生变化但存在副作用:

  • 在ListBox之前定义的DataGrid也在改变其ReadOnly状态。
  • ListBox中定义的DataGrids也遵循ListView中定义的Datagrids的ReadOnly属性。

在人们讲述重复之后更新:只是为了让人们知道。出现此问题的原因是使用相同的ItemsSource。引擎盖下将使用相同的CollectionView。与CollectionView相关的每个功能(例如排序顺序或IsReadOnly属性)都会受到具有相同ItemsSource的每个控件的影响(引擎盖下的Same CollectionView)。

为什么?

重现问题...只需执行正常的WPF应用程序并应用2个修改:

  1. 将MainWindow xaml更改为:

                      

    <ScrollViewer>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height ="Auto"></RowDefinition>
                <RowDefinition Height ="Auto"></RowDefinition>
                <RowDefinition Height ="Auto"></RowDefinition>
                <RowDefinition Height ="Auto"></RowDefinition>
                <RowDefinition Height ="Auto"></RowDefinition>
                <RowDefinition Height ="Auto"></RowDefinition>
            </Grid.RowDefinitions>
    
            <CheckBox Name="CheckBox"></CheckBox>
    
            <TextBlock Grid.Row="1" Text="{Binding Families.Count}"></TextBlock>
            <!--<Button Click="ButtonBase_OnClick"></Button>-->
    
            <DataGrid Grid.Row="2" ItemsSource="{Binding Familiy1.Persons}"
                    IsReadOnly="True">
            </DataGrid>
    
            <DataGrid Grid.Row="3" ItemsSource="{Binding Familiy1.Persons}"
                    IsReadOnly="false">
            </DataGrid>
    
            <ListBox Grid.Row="4" HorizontalContentAlignment="Stretch" 
                    ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
                    ItemsSource="{Binding Families}" Background="Khaki">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <GroupBox Header="ListBox">
                            <DataGrid ItemsSource="{Binding Persons}">
                            </DataGrid>
                        </GroupBox>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
    
            <ListView Grid.Row="5" 
                    ItemsSource="{Binding Families}"
                    Margin="0,24,0,0" Background="Thistle"
                    ScrollViewer.HorizontalScrollBarVisibility="Disabled">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <GroupBox>
                            <GroupBox.Header>
                                <TextBlock Text="ListView"></TextBlock>
                            </GroupBox.Header>
    
                            <DataGrid ItemsSource="{Binding Persons}"
                                    Background="Red" AutoGenerateColumns="True"
                                    ColumnWidth="Auto"
                                      IsReadOnly="{Binding IsChecked , ElementName=CheckBox}">
                            </DataGrid>
                        </GroupBox>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Grid>
    </ScrollViewer>
    

  2. 此外,添加以下MainWindowModel.cs类:

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    
    
    namespace WpfDataGridIsReadOnlyBug
    { 
    public class Person : INotifyPropertyChanged
    {
        private int _age;
        private string _name;
    
        public string Name
        {
            get { return _name; }
            set { _name = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name")); }
        }
    
        public int Age
        {
            get { return _age; }
            set { _age = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Age")); }
        }
    
        public Person()
        {
    
        }
    
        public Person(string name, int age)
        {
            Name = name;
            Age = age;
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    }
    
    public class Family : INotifyPropertyChanged
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name")); }
        }
    
        public Family()
        {
    
        }
    
        public Family(string name)
        {
            Name = name;
        }
        public ObservableCollection<Person> Persons { get; } = new ObservableCollection<Person>();
    
        public event PropertyChangedEventHandler PropertyChanged;
    
    }
    
    public class MainWindowModel
    {
        public ObservableCollection<Family> Families { get; } = new ObservableCollection<Family>();
    
        public Family Familiy1
        {
            get { return Families[0]; }
        }
    
        public MainWindowModel()
        {
            Family family = new Family("Family 1");
            family.Persons.Add(new Person("Eric", 50));
            family.Persons.Add(new Person("Isabel Lucas", 35));
            Families.Add(family);
    
            family = new Family("Family 2");
            family.Persons.Add(new Person("Candice Swanopel", 25));
            Families.Add(family);
        }
    }
    }
    

0 个答案:

没有答案