Member 14892534 Ответов: 1

Не удается захватить datagrid collectionviewsource вставить/удалить строку


I am looking for solution to the issue of insert new or delete of a datagrid row that is not being identified or captured by simply checking dbcontext.changetracker.haschanges status. HasChanges picks up when user modifies existing datagrid row but (as I have read) insert and delete on a datagrids itemssource that is set using a collectionviewsource as in my case is not recognized by HasChanges. The numerous discussions on internet of this have so far not led me to the solution which must be a commmon one if this design is itself common. The reason for this is me and my lack of knowledge (this is my first WPF, MVVM EF app), so I would like to get a working example to review and learn from.

Я привожу список элементов из базы данных, которые используются для заполнения combobox itemssource. Пользователь может захотеть добавить, удалить или изменить этот список, чтобы у меня было другое представление, из которого он может поддерживать этот список. Я могу иметь дело с действием modify, потому что оно автоматически распознается, когда я использую HasChanges, но я теряюсь в том, как определить, что произошла вставка или удаление строки. Если я могу понять, как определить или "захватить", когда это произошло, то я думаю, что знаю, как добавить/удалить это из своего класса, а затем сохранить его в базе данных.

Что я уже пробовал:

Я перепробовал всевозможные варианты привязки, xaml-дизайн datagrid и связанных с ним столбцов, читал о messenger и сервисах. Похоже, что чем больше я просматриваю интернет, тем сложнее он выглядит.

Один из моих датагридов выглядит следующим образом;

<pre>        <DataGrid x:Name="siteDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True"  Grid.Column="0" Grid.Row="3"

                  ItemsSource="{Binding GeneralSitesViewSource, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Margin="10,10,10,1" RowDetailsVisibilityMode="VisibleWhenSelected"

                  CellStyle="{StaticResource datagridcellstyle}" Height="110" Width="330">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="Site1Column" Binding="{Binding Site1}" Header="Site Name" Width="310"/>
            </DataGrid.Columns>
        </DataGrid>


Datagrid ItemsSource создается следующим образом;

private void FillGeneralSites()
                {
                    var q = (from a in Generalcontext.Sites
                             select a).ToList();
                _generalSites = new ObservableCollection<Site>(q);
GeneralSitesViewSource = CollectionViewSource.GetDefaultView(_generalSites);
GeneralSitesViewSource.SortDescriptions.Add(new SortDescription("Site1", ListSortDirection.Ascending));

        }
        public ICollectionView GeneralSitesViewSource { get; set; }
        private ObservableCollection<Site> _generalSites;
            public ObservableCollection<Site> GeneralSites
            {
                get
                {
                    return _generalSites;
                }
                set
                {
                    _generalSites = value;
                    OnPropertyChanged("GeneralSites");

                }
            }


В настоящее время установите проверку только с помощью HasChanges и если есть какие либо изменения в этом случае сохраните

public bool CanClose()
{
    //check if saved context then return true or false etc

    if (Generalcontext.ChangeTracker.HasChanges())
    {
        MessageBoxResult msgresult = MessageBox.Show("Changes were not saved. Do you want to save your changes before exiting?", "EXIT WINDOW",
            MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);
        if (msgresult == MessageBoxResult.Yes)
        {
            Generalcontext.SaveChanges();
            return true;
        }
        else if (msgresult == MessageBoxResult.No)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return true;
    }
}

1 Ответов

Рейтинг:
10

Gerry Schmitz

Слишком много "сцепления". Наблюдаемая коллекция не взаимодействует с контекстом данных. Вы добавляете обработчики событий в OC (т. е. CollectionChanged), которые взаимодействуют с контекстом данных.

Сущности в OC должны быть "отделены" от DbContext, если вы хотите сохранить свое здравомыслие.


Member 14892534

Джерри ценит, что ты нашел время ответить. Мне придется потратить время на то, чтобы переварить твой совет. Является ли то, о чем говорится в этом посте, тем же самым, что вы предлагаете? https://social.msdn.microsoft.com/Forums/en-US/b8f10fed-154d-4606-a777-dc6db578dd8d/observablecollection-and-oncollectionchanged?forum=wpf

Если так, то это снова заставит меня двигаться.

Первоначально я не использовал collectionviewsource для моего datagrid itemssource, а только наблюдаемую коллекцию, но я увидел предупреждение в окне VS immediate о том, что не очень хороший совет использовать, поэтому я изменил их все на collectionviewsource. это тоже позволило мне разобраться.

Gerry Schmitz

Если вы работаете с ObservableCollection, содержащей сущности, представляющие dbContext, но отсоединенные, то проще "отменить", проверить и управлять обновлениями. Событие "изменено" сообщает вам, что происходит в коллекции; вы можете решить передать это в dbContext на досуге. В противном случае вложенные объекты в вашем dbContext обновляются независимо от того, хотите вы этого или нет; затем вам нужно обновить базу данных.

Member 14892534

на самом деле, если я перестану пытаться разрешить пользователю напрямую редактировать строку и вместо этого заставлю их предоставить свои новые данные, если они хотят добавить строку, а затем они нажмут кнопку отправки, чтобы добавить строку, то управлять ею будет проще. Интересно, если это лучший дизайн, а также ввод данных может быть проверен.

Я думаю, что как новый кодер я страдаю от недостатка опыта в дизайне. Возможно, на этом этапе мне следует пойти на более простой дизайн, который может облегчить кодирование, а не иметь более продвинутый дизайн, который все еще находится за пределами моих знаний о кодировании.

Gerry Schmitz

Когда пользователь хочет отредактировать, я "показываю" форму или пользовательский элемент управления, оптимизированный для ввода / редактирования данных для выбранного элемента. В случае добавления я буду "переносить" данные из просматриваемого элемента, позволяя простое "клонирование" (если хотите). "Данные контроля въезда / форме" в действительности "сообщения" в ОС.

"Сетки" отлично подходят для просмотра, но редко для сложного ввода данных (и никогда быстрее).

Member 14892534

У меня есть 25 списков, которые пользователь может захотеть добавить/изменить. Конечно, я не хочу 25 просмотров (окон). Я собираюсь попробовать 25 datatemplates в словаре, которые дают мне xaml для каждого списка и меняют их местами в 1 winow и из него в зависимости от того, что пользователь хочет изменить. Понадобится 25 моделей просмотра, но они будут проще. Я проверю это вместе с приведенным выше предложением использовать обработчики событий и держать OC отделенным от DbContext.. по крайней мере, узнаю о словарях и datatempaltes, а также usercontrols и обмене представлениями, даже если это не удастся.

Gerry Schmitz

Просмотрите свои 25 списков и посмотрите, что в них общего.

Списки вполне могут быть обработаны с помощью одного набора универсального кода. Пользователь, как правило, редактирует один список за один раз; было бы редкостью, что ему нужно видеть 25 из них одновременно.

Все, что вам может понадобиться, - это "список / исходный код" в ваших записях.

Member 14892534

правильно, Спасибо Джерри, что дал мне направление, в котором я нуждаюсь.