首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF MVVM:在CRUD上没有刷新用户控制视图?

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

Stack Overflow用户
提问于 2014-09-09 15:27:34
回答 2查看 1.3K关注 0票数 0

我在MVVM模式中使用WPF。我正在使用实体框架。我有一个主窗口(应享权利视图)和一个选项卡控件。此视图中的选项卡项都绑定到作为用户控件的视图。

应享权利意见:

代码语言:javascript
复制
  <TabControl Grid.Row="1">
        <TabItem Header="Accounts" Content="{Binding AccountsViewModel}"/>
        <TabItem Header="Users" Content="{Binding UsersViewModel}"/>
    </TabControl>

App.Xaml.cs在初始化时实例化“应享权利”视图:

代码语言:javascript
复制
 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中:

代码语言:javascript
复制
 xmlns:vm="clr-namespace:DIEntitlements.ViewModels">            
 <UserControl.Resources>
    <vm:AccountsViewModel x:Key="AccountsViewModel"/>
 </UserControl.Resources>
<Grid DataContext="{StaticResource AccountsViewModel}">

ViewModel DataTemplates in App.Xaml:

代码语言:javascript
复制
  <ResourceDictionary>           
        <DataTemplate DataType="{x:Type vm:AccountsViewModel}">
            <v:AccountsView/>
        </DataTemplate>            
        <DataTemplate DataType="{x:Type vm:UsersViewModel}">
            <v:UsersView/>
        </DataTemplate>            
    </ResourceDictionary>  

&最后一点ViewModel代码:

财产:

代码语言:javascript
复制
    private ObservableCollection<tbUsername> _usersCollection;
    public ObservableCollection<tbUsername> UsersCollection
    {
        get { return _usersCollection; }
        set
        {
            _usersCollection = value;
            OnPropertyChanged("UsersCollection");
        }
    }

Linq方法:

代码语言:javascript
复制
  private void GetUserHeaders()
    {
        var query = from u in _context.tbUsernames
                    where u.accountId == SelectedAccountHeader.accountid
                    select u;

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

在第一个选项卡上,调用相应的ViewModel构造函数& UI按预期显示。当更改被持久化回数据库但UI没有刷新时,就会出现这个问题。我正在视图模型中正确地实现INotifyPropertyChanged。我认为这个问题产生于只在初始化时构造视图模型和视图的一个实例,然后保存在内存中&而不是在更改持续时重新初始化。是否有一种方法来刷新UI,而不会在UI中有一个笨重的“刷新”按钮?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-30 14:47:55

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

下面是我的RefreshEntities()方法,它调用MergeOption.OverwriteChanges;它实质上覆盖上下文实体&用来自DB的新数据重新加载集合。你在告诉EF覆盖你传入的实体。我在任何地方调用该方法,只要我坚持对该视图进行更改

代码语言:javascript
复制
   private void RefreshEntities()
    {
        var objectContext = ((IObjectContextAdapter)_context).ObjectContext;
        var objectSet = objectContext.CreateObjectSet<vwAccountHeader>();
        objectSet.MergeOption = MergeOption.OverwriteChanges;
        AccountHeaderCollection = new ObservableCollection<vwAccountHeader>(objectSet);
    }

看上去很详细,但效果很好。我建议在任何MVVM应用程序中更新UI中的视图,该视图通过与EF框架模型中的关联表的用户交互而改变。本质上,在表与视图之间存在交叉关系&您需要在UI中更新该视图。

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

票数 0
EN

Stack Overflow用户

发布于 2014-09-09 15:53:19

接下来是注释--看起来您正确地使用了ObservableCollection,但是集合中的对象并没有实现INotifyPropertyChanged,因为它们是直接来自DB的。

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

代码语言:javascript
复制
private int _displayNumber;

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

如果您不能费心做所有的转换,您可以使用AutoMapper进行传输。

因此,一般的流程是:

  1. 获取您正在做的数据
  2. 将其转换为在类中的每个属性上实现INotifyPropertyChanged的类。
  3. 添加到ObservableCollection中
  4. 绑定,因为您当前正在绑定

...then反向返回到DB的方式。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25748486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档