2014-09-29 3 views
0

У меня есть Datagrid на мой взгляд связано с ObservableCollection<T>. Сбор заполняется из метода, вызываемого в конструкторе viewmodel с использованием метода Linq to EF. который выбирает записи из представления в моем SQL сервер БД:Пользовательский интерфейс не обновляется с помощью WPF MVVM?

собственности:

private ObservableCollection<vwAccountHeader> _accountHeaderCollection; 
public ObservableCollection<vwAccountHeader> AccountHeaderCollection 
{ 
    get { return _accountHeaderCollection; } 
    set 
    { 
     _accountHeaderCollection = value; 
     OnPropertyChanged("AccountHeaderCollection"); 
    } 
} 

Метод:

private void GetAccountHeaders() 
{ 
    var query = from a in _context.vwAccountHeaders 
     select a; 

    AccountHeaderCollection = new ObservableCollection<vwAccountHeader>(query); 
} 

Выбранный элемент:

private vwAccountHeader _selectedAccountHeader; 
public vwAccountHeader SelectedAccountHeader 
{ 
    get { return _selectedAccountHeader; } 
    set 
    { 
     _selectedAccountHeader = value; 
     OnPropertyChanged("SelectedAccountHeader"); 
    } 
} 

Коллекция населяет, как ожидается инициализация. Я тогда функциональность для пользователя, чтобы выбрать строку из Datagrid и редактировать указанный ряд:

enter image description here

выбранных изменения пункта, сохраняются обратно в таблицу SQL не SQL Посмотреть привязанную к DataGrid однако это table является родительским элементом представления, поэтому изменения также сохраняются в представлении. Например вот моя SaveEdits команда:

private void SaveAccountEditsCommandAction() 
{ 
    var query = from a in _context.tbAccounts 
       where SelectedAccount.accountId == a.accountId 
       select a; 

    foreach (var a in query) 
    { 
     a.Div1AccNo = SelectedAccount.Div1AccNo; 
     a.AccountName = SelectedAccount.AccountName; 
     a.CompanyName = SelectedAccount.CompanyName; 
     a.ContactEmail = SelectedAccount.ContactEmail; 
     a.ContactName = SelectedAccount.ContactName; 
     a.SubscriptionLevel = SelectedAccount.SubscriptionLevel; 
     a.Responsible = SelectedAccount.Responsible; 
     a.notes = SelectedAccount.notes; 
     a.IsActive = SelectedAccount.IsActive; 
    } 

    _context.SaveChanges(); 
} 

Эти изменения сохранялись в моем VWAccountHeaders View в SQL Server. Я реализую INotifyPropertyChnaged и Xaml связывание установлено обновление на «PropertyChanged»:

<DataGrid x:Name="AccountsHeaderDataGrid" Margin="10" ItemsSource="{Binding AccountHeaderCollection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False" SelectedItem="{Binding SelectedAccountHeader, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
      IsReadOnly="True" CanUserAddRows="False" SelectionMode="Single" VerticalScrollBarVisibility="Auto" Height="350"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Header="Account No" Binding="{Binding Path=div1accno, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="SizeToHeader"/> 
      <DataGridTextColumn Header="Company Name" Binding="{Binding Path=companyname, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="SizeToHeader"/> 
      <DataGridTextColumn Header="Subscription Level" Binding="{Binding Path=subscriptionlevel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="SizeToHeader"/> 
      <DataGridTextColumn Header="Region List" Binding="{Binding Path=region_list, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="SizeToHeader"/> 
      <DataGridCheckBoxColumn Header="Is Active" Binding="{Binding Path=IsActive, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="SizeToHeader"/> 
     </DataGrid.Columns> 
<DataGrid/> 

Несмотря на это, я просто не могу получить пользовательский интерфейс, чтобы отразить изменения в исходных данных, не закрывая приложение & повторного запуска. Я вижу, что DataGrid мерцает при сохранении, поэтому может видеть, что он перевязывается, но он просто не подбирает изменения в базовом представлении. Мне нужно каким-то образом обновить контекст данных или я пропустил здесь что-то простое?

ответ

0

Хорошо, ребята. Я решил этот вопрос наконец!

Вот мой метод RefreshEntities(), который вызывает MergeOption.OverwriteChanges;, который по существу перезаписывает объект контекста. & перезагружает коллекцию новыми данными из БД. Вы хотите сказать, EF, чтобы перезаписать объект вы передаете в Я вызов этого метода, где я сохраняющиеся изменения этой точки зрения:.

private void RefreshEntities() 
    { 
     var objectContext = ((IObjectContextAdapter)_context).ObjectContext; 
     var objectSet = objectContext.CreateObjectSet<vwAccountHeader>(); 
     objectSet.MergeOption = MergeOption.OverwriteChanges; 
     AccountHeaderCollection = new ObservableCollection<vwAccountHeader>(objectSet); 
    } 

кажется очень многословным, но прекрасно работает. Я бы рекомендовал это для любого MVVM-приложения MVVM, в котором вы пытаетесь обновить представление в пользовательском интерфейсе, который был изменен путем взаимодействия пользователя с соответствующей таблицей в модели среды EF. По существу, там, где существует перекрестная взаимосвязь между таблицами &, вид & вам необходимо обновить этот вид в пользовательском интерфейсе.

MergeOption.OverwriteChanges перезаписывает все ожидающие изменения изменения, но вы можете использовать MergeOption.PreserveChanges, чтобы объединить перезагруженные значения только к вашим отредактированным значениям.

0

Возможно, проблема связана с тем, что коллекция не изменяется, и поэтому событие может не запускаться автоматически. Таким образом, в SaveAccountEditsCommandAction попытайтесь поднять изменения свойства для AccountHeaderCollection

+0

Нет, вы не должны поднимать изменение свойства в коллекции, потому что коллекция не изменилась. Это не привязка к стороне, которая не работает. – nilbot

+0

Правильно, ObservableCollection не изменился, объект объектов не привязан к изменениям. Но как исправить это? .. – Hardgraf

+0

@Hardgraf Is SelectedAccount клон оригинального или он относится к одному и тому же объекту в коллекции? –

0

создается Ваша коллекция только один раз, и это не волшебно освежает позже. Попробуйте вызвать GetAccountHeaders() в конце SaveAccountEditsCommandAction().

+0

Пробовал это, коллекция такая же. Похоже, что объект vwAccountHeader EF не взял изменения из db – Hardgraf

+0

Итак, изменения хранятся в db, но EF не выбирает их, если вы не перезапустите приложение? Вы пробовали выбирать данные из БД после нажатия кнопки «Сохранить». Они уже находятся в БД. Также вы можете установить точку останова при вызове GetAccountHeaders() в конце SaveAccountEditsCommandAction(). Загружаются ли данные в актуальном состоянии? –

+0

Точно. Данные в db сохранялись при вызове GetAccountHeaders(), но запрос linq не подбирает изменения из _context.vwAccountHeaders ... – Hardgraf

Смежные вопросы