У DataGrid после сохранения поля становятся пустыми. Как исправить?

У меня есть элемент DataGrid, с 4 колонками типа ComboBox. Все заполняется отлично, однако после сохранения и переоткрытия окна - поля строк отображаются пустыми. введите сюда описание изображения

WPF:

<DataGrid x:Name="datagrid" AutoGenerateColumns="False" ItemsSource="{Binding Items}" SelectionMode="Single" Grid.ColumnSpan="5" Grid.Row="1" CanUserReorderColumns="False" CanUserSortColumns="False" CanUserAddRows="False" RowDetailsVisibilityMode="Visible" SelectedItem="{Binding SelectedItem}" SelectedIndex="{Binding SelectedIndex}" >
<DataGrid.Columns>
    <DataGridComboBoxColumn Header="Kind:" Width="25*" SelectedItemBinding="{Binding Kind, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="KindId" DisplayMemberPath="KindName">
        <DataGridComboBoxColumn.ElementStyle>
            <Style TargetType="ComboBox">
                <Setter Property="ItemsSource" Value="{Binding KindItems}"/>
            </Style>
        </DataGridComboBoxColumn.ElementStyle>
        <DataGridComboBoxColumn.EditingElementStyle>
            <Style TargetType="{x:Type ComboBox}">
                <EventSetter Event="SelectionChanged" Handler="SomeSelectionChanged" />
                <Setter Property="ItemsSource" Value="{Binding KindItems}"/>
            </Style>
        </DataGridComboBoxColumn.EditingElementStyle>
    </DataGridComboBoxColumn>
    <DataGridComboBoxColumn Header="Name:" Width="25*" SelectedItemBinding="{Binding Theme, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="FieldId" DisplayMemberPath="FieldName">
        <DataGridComboBoxColumn.ElementStyle>
            <Style TargetType="ComboBox">
                <Setter Property="ItemsSource" Value="{Binding ThemeItems}"/>
            </Style>
        </DataGridComboBoxColumn.ElementStyle>
        <DataGridComboBoxColumn.EditingElementStyle>
            <Style TargetType="ComboBox">
                <Setter Property="ItemsSource" Value="{Binding ThemeItems}"/>
            </Style>
        </DataGridComboBoxColumn.EditingElementStyle>
    </DataGridComboBoxColumn>
    <DataGridComboBoxColumn Header="Start:" Width="25*" SelectedItemBinding="{Binding Start, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="FieldId" DisplayMemberPath="FieldName">
        <DataGridComboBoxColumn.ElementStyle>
            <Style TargetType="ComboBox">
                <Setter Property="ItemsSource" Value="{Binding StartItems}"/>
            </Style>
        </DataGridComboBoxColumn.ElementStyle>
        <DataGridComboBoxColumn.EditingElementStyle>
            <Style TargetType="ComboBox">
                <Setter Property="ItemsSource" Value="{Binding StartItems}"/>
            </Style>
        </DataGridComboBoxColumn.EditingElementStyle>
    </DataGridComboBoxColumn>
    <DataGridComboBoxColumn Header="End:" Width="25*" SelectedItemBinding="{Binding End, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="FieldId" DisplayMemberPath="FieldName">
        <DataGridComboBoxColumn.ElementStyle>
            <Style TargetType="ComboBox">
                <Setter Property="ItemsSource" Value="{Binding EndItems}"/>
            </Style>
        </DataGridComboBoxColumn.ElementStyle>
        <DataGridComboBoxColumn.EditingElementStyle>
            <Style TargetType="ComboBox">
                <Setter Property="ItemsSource" Value="{Binding EndItems}"/>
            </Style>
        </DataGridComboBoxColumn.EditingElementStyle>
    </DataGridComboBoxColumn>
</DataGrid.Columns>

C#:

internal partial class CalendarDialog : Window, INotifyPropertyChanged, IComponentConnector
{
    private readonly IServiceProvider serviceProvider;
    private readonly ICContextProvider contextProvider;

    private ICommand addItemCommand;
    private ICommand removeItemCommand;
    private ICommand okCommand;
    private ICommand cancelCommand;
    private ICommand cheatCommand;

    private ObservableCollection<CalendarMetaItem> items;
    private CalendarMetaItem selectedItem;
    private List<KindModel> kindItems;

    public int SelectedIndex { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    public CalendarDialog(IServiceProvider serviceProvider)
    {
        InitializeComponent();
            
        this.serviceProvider = serviceProvider;
        contextProvider = new ServiceHelper(serviceProvider).ContextProvider;

        this.Loaded += CalendarDialog_Loaded;
    }

    private void CalendarDialog_Loaded(object sender, RoutedEventArgs e)
    {
        this.UpdateLayout();
    }

    public void Initialize(List<CalendarMetaItem> items)
    {
        Items = new ObservableCollection<CalendarMetaItem>();
        var completeItems = items;
        InitKindItems();
            
        foreach (var item in completeItems ?? Enumerable.Empty<CalendarMetaItem>())
        {
            var fields = InitKindFields(new Guid(item.Kind.TypeId));
            Items.Add(new CalendarMetaItem
            {
                Kind = item?.Kind,
                Theme = item?.Theme,
                Start = item?.Start,
                End = item?.End,
                KindItems = new ObservableCollection<KindModel>(kindItems),
                ThemeItems = new ObservableCollection<FieldModel>(fields?.StringFields),
                StartItems = new ObservableCollection<FieldModel>(fields?.DateFields),
                EndItems = new ObservableCollection<FieldModel>(fields?.DateFields)
            });
        }
        UpdateLayout();
    }

    private void InitKindItems()
    {
        var context = currentContextProvider.GetContext();
        var kindService = context.GetService<IKindService>();
        var types = kindService.Kinds.Types;
        var allKinds = new List<KindModel>();
        foreach (var type in types)
        {
            if (type.CardTypeId.Equals(CardDocument.ID) || type.CardTypeId.Equals(CardTask.ID))
            {
                var typeId = type.Id.ToString();
                var rootKindId = type.RootKind.Id.ToString();
                var rootKindProto = new KindModel();
                rootKindProto.TypeId = typeId;
                rootKindProto.KindId = rootKindId;
                rootKindProto.Level = 0;
                rootKindProto.KindName = type.RootKind.Name;
                rootKindProto.ParentKindId = Guid.Empty.ToString();
                allKinds.Add(rootKindProto);

                foreach (var kind in type.Kinds)
                {
                    var level = 2;
                    var kindProto = new KindModel();
                    kindProto.TypeId = typeId;
                    kindProto.Level = 1;
                    kindProto.KindName = kind.Name;
                    kindProto.KindId = kind.Id.ToString();
                    kindProto.ParentKindId = rootKindId;
                    allKinds.Add(kindProto);
                    searchR(allKinds, level, kind, typeId);
                }
            }
        }
        kindItems = allKinds;
    }
    private void searchR(List<KindModel> allKinds, int level, KindsCardKind kind, string typeId)
    {
        if (kind.Kinds.Count > 0)
        {
            foreach (var k in kind.Kinds)
            {
                var kindProto = new KindModel();
                kindProto.TypeId = typeId;
                kindProto.Level = level;
                kindProto.KindName = k.Name;
                kindProto.KindId = k.Id.ToString();
                kindProto.ParentKindId = kind.Id.ToString();
                allKinds.Add(kindProto);
                level++;
                searchR(allKinds, level, k, typeId);
            }
        }
    }

    private KindFields InitKindFields (Guid typeId)
    {
        var context = currentContextProvider.GetContext();
        var data = context.GetService<IDataProvider>().GetData(typeId);
        var stringFields = new List<FieldModel>();
        var dateFields = new List<FieldModel>();
        foreach (var table in data.Tables)
        {
            var sectName = table.Name;
            var sectId = table.Id;
            foreach (var field in table.Fields)
            {
                if (field.Type == FieldType.String)
                {
                    var myField = new FieldModel();
                    myField.SectionName = sectName;
                    myField.SectionId = sectId.ToString();
                    myField.FieldName = field.Name;
                    myField.FieldId = field.Id.ToString();
                    stringFields.Add(myField);
                }
                if (field.Type == FieldType.DateTime)
                {
                    var myField = new FieldModel();
                    myField.SectionName = sectName;
                    myField.SectionId = sectId.ToString();
                    myField.FieldName = field.Name;
                    myField.FieldId = field.Id.ToString();
                    dateFields.Add(myField);
                }

            }
        }
        return new KindFields
        {
            StringFields = stringFields,
            DateFields = dateFields
        };
    }

    public CalendarMetaItem SelectedItem
    {
        get
        {
            return this.selectedItem;
        }
        set
        {
            SetField(ref this.selectedItem, value);
        }
    }

    public ObservableCollection<CalendarMetaItem> Items
    {
        get
        {
            return this.items;
        }
        set
        {
            SetField(ref this.items, value, "Items");
        }
    }

    public ICommand AddItemCommand
    {
        get
        {
            return this.addItemCommand ?? (this.addItemCommand = new RelayCommand(this.AddItem));
        }
    }

    public ICommand RemoveItemCommand
    {
        get
        {
            return this.removeItemCommand ?? (this.removeItemCommand = new RelayCommand(this.RemoveItem, this.CanRemoveItem));
        }
    }

    public ICommand OkCommand
    {
        get
        {
            return this.okCommand ?? (this.okCommand = new RelayCommand(this.Ok, this.CanOk));
        }
    }

    public ICommand CancelCommand
    {
        get
        {
            return this.cancelCommand ?? (this.cancelCommand = new RelayCommand(this.Cancel));
        }
    }

    public ICommand CheatCommand
    {
        get
        {
            return this.cheatCommand ?? (this.cheatCommand = new RelayCommand(this.Cheat));
        }
    }

    private void AddItem()
    {
        var item = new CalendarMetaItem();
        item.KindItems = new ObservableCollection<KindModel>(kindItems);
        this.Items.Add(item);
    }
    private bool CanRemoveItem(object obj)
    {
        return SelectedItem != null;
    }

    private void RemoveItem()
    {
        Items.Remove(SelectedItem);
    }

    private void Cancel()
    {
        base.DialogResult = false;
        Close();
    }
    private void Ok()
    {
        base.DialogResult = true;
        Close();
    }

    private bool CanOk(object obj)
    {
        return true;
    }

    private void SomeSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var comboBox = sender as ComboBox;
        var item = comboBox.SelectedItem as KindModel;
        var fields = InitKindFields(new Guid(item.TypeId));

        DataGridRow row = (DataGridRow) datagrid.ContainerFromElement(comboBox);
        int rowIndex = row.GetIndex();
        Items[rowIndex].ThemeItems = new ObservableCollection<FieldModel>(fields.StringFields);
        Items[rowIndex].StartItems = new ObservableCollection<FieldModel>(fields.DateFields);
        Items[rowIndex].EndItems = new ObservableCollection<FieldModel>(fields.DateFields);
    }

    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        RaisePropertyChanged(propertyName);
    }

    private void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
        if (propertyChanged != null)
        {
            PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
            propertyChanged(this, e);
        }
    }

    private bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(field, value))
        {
            return false;
        }
        field = value;
        RaisePropertyChanged(propertyName);
        return true;
    }
}

Models:

class CalendarMetaItem : INotifyPropertyChanged
{        
    private KindModel kind;
    private FieldModel theme;
    private FieldModel start;
    private FieldModel end;
        
    public KindModel Kind
    {
        get
        {
            return this.kind;
        }
        set
        {
            this.kind = value;
            NotifyPropertyChanged("Kind");
        }
    }

    [JsonIgnore]
    public ObservableCollection<KindModel> KindItems { get; set; }

    public FieldModel Theme
    {
        get
        {
            return this.theme;
        }
        set
        {
            this.theme = value;
            NotifyPropertyChanged("Theme");
        }
    }

    [JsonIgnore]
    public ObservableCollection<FieldModel> ThemeItems { get; set; }

    public FieldModel Start
    {
        get
        {
            return this.start;
        }
        set
        {
            this.start = value;
            NotifyPropertyChanged("Start");
        }
    }

    [JsonIgnore]
    public ObservableCollection<FieldModel> StartItems { get; set; }

    public FieldModel End
    {
        get
        {
            return this.end;
        }
        set
        {
            this.end = value;
            NotifyPropertyChanged("End");
        }
    }

    [JsonIgnore]
    public ObservableCollection<FieldModel> EndItems { get; set; }

    #region INotifyPropertyChanged implementation

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

Ответы (0 шт):