为什么我收到的“物品收藏一定是空的”?嵌套数据网格异常

本文关键字:嵌套 数据 网格 数据网 异常 为什么 收藏 | 更新日期: 2023-09-27 18:16:26

我使用嵌套datagrid来管理嵌套类集合的类。

每个嵌套类由一个单元格模板表示。

这是一个重现问题的最小模型:

using System.ComponentModel;
using System.Linq;
namespace ICMBE{
    public class Outer : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;
        private Nested1[ ] _categories = Enumerable.Range( 1, 1
                    ).Select( n => new Nested1( ) ).ToArray( );
        public Nested1[ ] Categories {
            get { return this._categories; }
        }
    }
    public class Nested1 : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;
        private Nested2[ ] _questions = Enumerable.Range( 1, 5
                    ).Select( n => new Nested2( ) ).ToArray( );
        public Nested2[ ] Questions {
            get { return this._questions; }
        }
    }
    public class Nested2 : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;
        private Nested3[] _answers = Enumerable.Range( 1, 5
                ).Select( n => new Nested3( ) ).ToArray( );
        public Nested3[ ] Answers {
            get { return this._answers; }
        }
    }
    public class Nested3 : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;
        private string _foo = "Bar";
        public string Foo { get { return this._foo; } }
    }
}

创建一个字段值并在应用程序中公开:

using System.ComponentModel;
namespace IMCBE{
    public partial class App : INotifyPropertyChanged {
        public event PropertyChangedEventHandler PropertyChanged;
        private Outer _outer = new Outer( );
    }
}
namespace IMCBE{
public partial class Program {
        /// <summary>
        /// Bla bla bla
        /// </summary>
        public Outer Outer{
            get { return this._outer; }
        }
    }
}

使用此窗口-

<Window
    x:Class="ICMBE.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Controls="clr-namespace:WPFTools.Controls;assembly=WPFTools"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WhyAreMyRowNumbersChanging"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <!-- Answers -->
        <DataTemplate x:Key="dtAnswerTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="100" />
                    <ColumnDefinition Width="5" />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <ToggleButton>
                    <Viewbox>
                        <TextBlock Text="Correct" />
                    </Viewbox>
                </ToggleButton>
                <TextBox Text="Bar" />
            </Grid>
        </DataTemplate>
        <!-- Questions -->
        <DataTemplate x:Key="dtQuestionTemplate">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="25" />
                    <RowDefinition Height="5" />
                    <RowDefinition Height="25" />
                    <RowDefinition Height="5" />
                    <RowDefinition Height="50" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="128" />
                    <ColumnDefinition Width="5" />
                    <ColumnDefinition Width="128" />
                    <ColumnDefinition Width="5" />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Viewbox Grid.ColumnSpan="3">
                    <TextBlock Text="Question" />
                </Viewbox>
                <TextBox Grid.Row="2" Grid.ColumnSpan="3" Text="Foo" />
                <ToggleButton Grid.Row="4">
                    <Viewbox>
                        <TextBlock Text="Bonus" />
                    </Viewbox>
                </ToggleButton>
                <Button Grid.Row="4" Grid.Column="2" />
                <Viewbox Grid.Column="4">
                    <TextBlock Text="Answers" />
                </Viewbox>
                <DataGrid
                    AutoGenerateColumns="False" CanUserAddRows="False"
                    CanUserDeleteRows="False" Grid.Column="4"
                    Grid.RowSpan="4" ItemsSource="{Binding Nested}">
                    <DataGridTemplateColumn
                        Width="*"
                        CellTemplate="{StaticResource dtAnswerTemplate}" />
                </DataGrid>
            </Grid>
        </DataTemplate>
        <!-- Categories -->
        <DataTemplate x:Key="dtCategoryTemplate">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="25" />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="256" />
                    <ColumnDefinition Width="5" />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Viewbox>
                    <TextBlock Text="Outer"/>
                </Viewbox>
                <DataGrid
                    AutoGenerateColumns="False" CanUserAddRows="False"
                    CanUserDeleteRows="False" Grid.Row="2"
                    Grid.ColumnSpan="3" HeadersVisibility="None"
                    ItemsSource="{Binding Nested}">
                    <DataGrid.Columns>
                        <DataGridTemplateColumn
                            Width="*"
                            CellTemplate="{StaticResource dtQuestionTemplate}" />
                    </DataGrid.Columns>
                </DataGrid>
            </Grid>
        </DataTemplate>
    </Window.Resources>
    <DataGrid
        Grid.Row="1"
        ItemsSource="{Binding Outer.Nested, Source={x:Static Application.Current}}"
        MaxHeight="Infinity" ScrollViewer.CanContentScroll="True">
        <DataGrid.Columns>
            <DataGridTemplateColumn
                Width="*" CellTemplate="{StaticResource dtCategoryTemplate}" />
        </DataGrid.Columns>
    </DataGrid>
</Window>

运行这个会导致程序崩溃。例外是"Items collection必须为空"。

从我所读到的,如果你设置ItemsItemsSource都设置了,就会发生这种情况,但这里没有发生这种情况。

为什么会发生这种崩溃?

为什么我收到的“物品收藏一定是空的”?嵌套数据网格异常

从我所读到的,如果你设置Items和ItemsSource,就会发生这种情况

这实际上是错误的原因,因为你忘了把一个<DataGrid.Columns>标签在datagridtemplatecoluml在dtQuestionTemplate DataTemplate的DataGrid。

应该是这样的:

<DataGrid ... ItemsSource="{Binding Nested}">
    <DataGrid.Columns>
        <DataGridTemplateColumn
            Width="*" CellTemplate="{StaticResource dtAnswerTemplate}" />
    </DataGrid.Columns>
</DataGrid>