【问题标题】:Model and ViewModel Consept MVVM WPF模型和视图模型概念 MVVM WPF
【发布时间】:2019-01-08 15:09:33
【问题描述】:

我想从数据库中读取一些数据并对它们进行一些处理,然后在视图中查看它们。 我读了很多关于 MVVM 的内容,现在我很困惑。 成像我从具有 Name 属性的数据库中读取了一个人实体。

请编写一个小代码,告诉我应该如何制作模型和 ViewModel。 我想我们会是这样的:

    public class PersonModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string Name;
        public string name
        {
            get
            {
                return Name;
            }
            set
            {
                Name = value;
                onpropertychanged("name");
            }


        }
        public PersonModel( string s)
        {
            name = s;
        }

        public void onpropertychanged(string PName)
        {
            if (PropertyChanged !=null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(PName));
            }
        }
    }

public  class PersonViewModel
    {
        public ObservableCollection <PersonModel> list { get; set; }

        public PersonViewModel()
        {
            list = new ObservableCollection<model>();
            list.Add(new model("abc"));
            list.Add(new model("def"));
       }

       public void change()
        {
            list[1].name = "changed";
        }

    }


public  class ViewModelBase
    {
        public PersonViewModel vperson { get; set; }
        public ViewModelBase()
        {
            vperson = new PersonViewModel();
            vperson.change();
        }
    }

编辑:数据库连接应该在哪里?

编辑:

    <Grid>
        <TextBox Text="{Binding vperson.list[1].name}" />
    </Grid>
</Window>

【问题讨论】:

  • 不用在模型中提供INotifyPropertyChanged,您可以在 ViewModel 中实现它(因为该接口用于 View 和 ViewModel 之间的通信)并将数据存储在 Model 中。然后,您从服务层中的数据库检索数据并将其映射到您的模型。
  • @FCin 您的意思是在 ViewModel 中制作和完全相同的类并将属性设置为等于模型类? (正如我在 MVVM 示例中看到的那样)但我为什么要这样做?
  • 但是请注意,在模型类中实现 INotifyPropertyChanged 并没有错。
  • @Clemens 你知道我同意我们不必在模型中使用 INotifyProPertyChanged,因为我认为视图和模型之间的每一个关系都必须通过视图模式,但这段代码是我为这个道具找到的唯一方法。
  • 在模型中实现 INPC 的问题在于,如果你这样做了,那么你通常也希望将集合更改通知放在那里。与 INPC 不同,ORM 不会为您创建 ObservableCollection(比如说),除非您覆盖它们的实体映射。在数据库检索后简单地用 ObservableCollections 替换列表是行不通的,因为 ORM 会认为列表本身已更改,并在您完成后再次将它们全部保存,从而使您的应用程序陷入困境。像 INPC 一样可以做到,我在 EF 和 NHibernate 中都做过,但它比最初看起来要复杂一些。

标签: c# wpf mvvm


【解决方案1】:

我编辑了你的课程并且正在工作

public class PersonModel : INotifyPropertyChanged
{
    private string _name;

    public string Name
    {
        get => _name;
        set
        {
            if (_name == value) return;

            _name = value;
            OnPropertyChanged();
        }
    }

    public PersonModel(string name)
    {
        _name = name;
    }

    public event PropertyChangedEventHandler PropertyChanged;

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

public class PersonViewModel
{
   public ObservableCollection<PersonModel> Items { get; set; }

   public PersonViewModel()
   {
       Items = new ObservableCollection<PersonModel> { new PersonModel("abc"), new PersonModel("def") };
   }

   public void Change()
   {
       Items[1].Name = "changed";
   }
}

public class ViewModelBase
{
    public PersonViewModel PersonViewModel { get; set; }

    public ViewModelBase()
    {
        PersonViewModel = new PersonViewModel();
        PersonViewModel.Change();
    }
}

//Use the dataContext in this way, will help you with the strong type
xmlns:viewModels="clr-namespace:WpfApp1.ViewModels"

<Window.DataContext>
    <viewModels:ViewModelBase />
</Window.DataContext>
<Grid>
    <TextBox Text="{Binding PersonViewModel.Items[1].Name}" />
</Grid>

【讨论】:

  • 我需要 ViewModelBase,因为我将使用许多其他 ViewModel 类,然后我将在 ViewModelBase 中一起使用它们。现在我也可以将我想要的所有内容绑定到 PersonViewModel,因为我的 ViewModelBase 类中有一个实例,如下所示:{Binding viem.list[1].name}
  • 您可以添加您的 view.xaml 吗?
  • 您需要将 Window.DataContext 连接到您的视图模型
  • xmlns:vm="clr-namespace:WpfApplication3.ViewModels"
  • 我在代码隐藏中做到了:this.DataContext = new ViewModelBase();
猜你喜欢
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 2010-12-07
  • 2020-01-17
相关资源
最近更新 更多