【问题标题】:WPF: יhow to populate my ViewModel in XAML instead of code behindWPF:יhow 在 XAML 中填充我的 ViewModel 而不是后面的代码
【发布时间】:2019-01-05 06:28:13
【问题描述】:

所以我有这个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 中执行此操作吗?或者这是正确的方法?

【问题讨论】:

    标签: wpf mvvm binding


    【解决方案1】:

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

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

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

    此示例使用 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>
    

    【讨论】:

      【解决方案2】:

      是的,你可以。但是不,你肯定不想这样做。

      要回答您的问题,假设您的 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>
      

      结果是这样的:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-26
        • 1970-01-01
        • 2012-02-03
        • 2011-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-16
        相关资源
        最近更新 更多