WPF MVVM:用户控制视图在CRUD上没有刷新?

时间:2014-09-09 15:27:35

标签: c# wpf xaml mvvm

我在MVVM模式中使用WPF。我正在使用实体框架。我有一个带有选项卡控件的主窗口(Entitlements视图)。此视图中的选项卡项目均绑定到用户控件的视图。

enter image description here

权利观点:

  <TabControl Grid.Row="1">
        <TabItem Header="Accounts" Content="{Binding AccountsViewModel}"/>
        <TabItem Header="Users" Content="{Binding UsersViewModel}"/>
    </TabControl>

App.Xaml.cs在初始化时实例化Entitlements视图:

 public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        var mainWindow = new MainWindow();
        var viewModel = new EntitlementsViewModel();
        mainWindow.DataContext = viewModel;
        mainWindow.Show();
    }
}

DataContext在View Xaml中设置:

 xmlns:vm="clr-namespace:DIEntitlements.ViewModels">            
 <UserControl.Resources>
    <vm:AccountsViewModel x:Key="AccountsViewModel"/>
 </UserControl.Resources>
<Grid DataContext="{StaticResource AccountsViewModel}">

App.Xaml中的ViewModel DataTemplates:

  <ResourceDictionary>           
        <DataTemplate DataType="{x:Type vm:AccountsViewModel}">
            <v:AccountsView/>
        </DataTemplate>            
        <DataTemplate DataType="{x:Type vm:UsersViewModel}">
            <v:UsersView/>
        </DataTemplate>            
    </ResourceDictionary>  

&安培;最后一点ViewModel代码:

属性:

    private ObservableCollection<tbUsername> _usersCollection;
    public ObservableCollection<tbUsername> UsersCollection
    {
        get { return _usersCollection; }
        set
        {
            _usersCollection = value;
            OnPropertyChanged("UsersCollection");
        }
    }

Linq方法:

  private void GetUserHeaders()
    {
        var query = from u in _context.tbUsernames
                    where u.accountId == SelectedAccountHeader.accountid
                    select u;

        UsersCollection = new ObservableCollection<tbUsername>(query);
    }       

在第一个选项卡选择中,调用相应的ViewModel构造函数&amp; UI按预期显示。当更改持久保存回数据库但UI未刷新时,会出现此问题。我正在View Models中正确实现INotifyPropertyChanged。我认为这个问题源于只有视图模型和视图的1个实例在初始化时构建,然后保存在内存和放大器中。保持更改时不重新初始化。有没有一种方法可以刷新用户界面而不需要笨重的刷新&#39;按钮&#39;在用户界面?

2 个答案:

答案 0 :(得分:0)

从评论开始 - 看起来你正在使用ObservableCollection,但是该集合中的对象没有实现INotifyPropertyChanged,因为它们直接来自数据库。

我建议你需要另一层,你可以转换这些&#39; POCO&#39;将对象转换为实现INotifyPropertyChanged的类。您可以继承BindableBase。要使用它创建属性,属性将如下所示:

private int _displayNumber;

public int DisplayNumber
{
  get { return _displayNumber; }
  set { SetProperty(ref _displayNumber, value); }
}

如果您无法完成所有转换操作,可以使用AutoMapper进行转移。

所以一般的流程是:

  1. 获取正在进行的数据
  2. 将其转换为在类中的每个属性上实现INotifyPropertyChanged 的类。
  3. 添加到ObservableCollection
  4. 绑定当前正在绑定
  5. ...然后反过来将它送回数据库。

答案 1 :(得分:0)

经过多次修补后,我已经解决了这个问题。

这是我的RefreshEntities()方法,它调用MergeOption.OverwriteChanges;它基本上覆盖了上下文实体&amp;使用来自DB的新数据重新加载集合。你告诉EF覆盖你传入的实体。我正在调用这个方法,只要我坚持改变那个视图

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

看起来非常冗长,但效果很好。我建议您在任何MVVM WPF应用程序中尝试更新UI中的视图,该视图已通过用户与EF框架模型中的关联表的交互而发生更改。基本上表格和表格之间存在交叉关系。一个观点&amp;您需要在UI中更新该视图。

MergeOption.OverwriteChanges会覆盖所有挂起的更改,但您可以使用MergeOption.PreserveChanges将重新加载的值合并到您编辑的值中。