WPF:如何在XAML中填充我的ViewModel而不是后面的代码

时间:2019-01-05 06:28:14

标签: wpf mvvm binding

所以我有这个ViewModel class

public class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private ObservableCollection<Person> _persons;

        public ObservableCollection<Person> Porsons
        {
            get { return _persons; }
            set
            {
                _persons = value;
                NotifyPropertyChanged();
            }
        }

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

然后创建此ViewModel class并填充其Person列表:

ViewModel viewModel;
ObservableCollection<Person> persons

public MainWindow()
{
    InitializeComponent();
    viewModel = new ViewModel();
    viewModel.Porsons= persons;
}

然后是我的ListView

<ListView ItemSource={Binding Persons}/>

因此,与其将这个Persons列表绑定到我的ViewModel class中,然后再执行此操作ItemSource,我可以纯粹地XAML进行操作,或者这就是正确的方法?

2 个答案:

答案 0 :(得分:0)

建议不要在视图上创建ViewModel属性,而应使用DataContext (this link also shows how to set it using XAML)。同样,不要在视图中填充视图模型,因为大多数时候数据都驻留在模型中,并且视图不应该了解任何模型(在遵循MVVM时)。

请阅读上面的链接,然后访问您遇到的链接。另请阅读此article about MVVM。这为您提供了一些基础知识,使您更容易理解如何使用WPF框架。

XAML中创建视图模型有很多变体。 例如,您也可以在App.Xaml中创建它,以使其可以通过StaticResource标记扩展名全局访问,并通过DataContext将其分配给各个控件的Style或使用{{ 3}}。

此示例使用XAML属性元素声明直接在目标视图中创建ViewModel实例。该实例只能在本地访问。

ViewModel.cs:

namespace Example
{
  public class ViewModel : INotifyPropertyChanged
  {       
    public ViewModel()
    {
      this.Persons = new ObservableCollection<Person>();
    }

    private ObservableCollection<Person> _persons;
    public ObservableCollection<Person> Persons
    {
      get => _persons;
      set
      {
        _persons = value;
        NotifyPropertyChanged();
      }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
  }
}

View.xaml:

<Window x:Class="Example.MainWindow"
        ...
        xmlns:local="clr-namespace:Example">

  <Window.DataContext>
    <local:ViewModel />
  </Window.DataContext>

  <Grid>
    <ListView ItemSource={Binding Persons}/>
  </Grid>
</Window>

答案 1 :(得分:0)

是的,可以。但是,不,您最不希望这样做。

要回答您的问题,假设您的Person类看起来像这样:

public class Person
{
    public string Name { get; set; }
}

您可以轻松地在XAML中声明一个列表并将其绑定到ListView(例如),如下所示:

<ListView DisplayMemberPath="Name">
    <ListView.ItemsSource>
        <x:Array Type="{x:Type vm:Person}">
            <vm:Person Name="Tom" />
            <vm:Person Name="Dick" />
            <vm:Person Name="Harry" />
        </x:Array>
    </ListView.ItemsSource>
</ListView>

其结果是这样的:

enter image description here

尽管您可以执行此操作,但这并不意味着您应该这样做。 MVVM的全部目的是将视图层与视图模型层分开。您应该能够从测试版本中运行整个应用程序,而根本不创建单个视图对象。在问这个问题时,您显然想做的是在视图层中声明一个数据结构,这完全是错误的放置位置。您的视图层应尽可能“哑巴”,只有与实际逻辑正在进行的视图模型层的绑定尽可能弱。