c# - 当 ViewModel 改变时如何让 View 更新

标签 c# wpf mvvm

我正在构建一个 WPF 应用程序来管理存储在 SharePoint 列表中的学生数据库。我是使用 MVVM 的新手,并且已经阅读了一些教程。我已经成功地创建了一个 View 和模型,并设法将它绑定(bind)到一个数据网格控件。我想做的是根据组合框的输出更新 View 中的数据。

这是我的模型:

using System.ComponentModel;

namespace StudentManagement.Model
{
public class Student : INotifyPropertyChanged
{
    private string _Title;
    private string _FullName;

    public string Title
    {
        get { return _Title; }
        set
        {
            if (_Title != value)
            {
                _Title = value;
                RaisePropertyChanged("Title");
            }
        }
    }

    public string FullName
    {
        get { return _FullName; }
        set
        {
            if (_FullName != value)
            {
                _FullName = value;
                RaisePropertyChanged("FullName");
            }

        }

    }



    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    } 
  }
}

这是 View 模型:
using System.Collections.ObjectModel;
using StudentManagement.Model;
using SP = Microsoft.SharePoint.Client;
using StudentManagement.publicClasses;

namespace StudentManagement.ViewModel
{
    public class StudentViewModel
    {
        public ObservableCollection<Student> Students { get; set; }

        public void LoadStudents(string query)
        {


           ObservableCollection<Student> _students = new 
        ObservableCollection<Student>();

        SP.ClientContext ctx = clientContext._clientContext;

        SP.CamlQuery qry = new SP.CamlQuery();
        qry.ViewXml = query;
        SP.ListItemCollection splStudents = 
 ctx.Web.Lists.GetByTitle("Students").GetItems(qry);
        ctx.Load(splStudents);
        ctx.ExecuteQuery();

        foreach (SP.ListItem s in splStudents)
        {
            _students.Add(new Student { Title = (string)s["Title"], FullName = (string)s["FullName"] });
        }
        Students = _students;

        }
    }
}

这是我的 XAML

<UserControl x:Class="StudentManagement.Views.StudentsView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
  
             xmlns:local="clr-namespace:StudentManagement.Views" >


    <Grid>

        <StackPanel HorizontalAlignment="Left" Width="200" >
            <TextBox Name="txtSearch" AcceptsReturn="True" ></TextBox>
            <ComboBox Name="cmbStatus"  SelectionChanged="cmbStatus_SelectionChanged" SelectedIndex="0">
                <ComboBoxItem>Active</ComboBoxItem>
                <ComboBoxItem>Inquiring</ComboBoxItem>
                <ComboBoxItem>Inactive</ComboBoxItem>
                <ComboBoxItem>Monitoring</ComboBoxItem>
            </ComboBox>
            <DataGrid Name="dgStudentList" ItemsSource="{Binding Path=Students}" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Name" Binding="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="100"/>
                    <DataGridTextColumn Header="Parent" Binding="{Binding FullName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="100" />
                </DataGrid.Columns>
            </DataGrid>
        </StackPanel>
    </Grid>
</UserControl>


...以及 View 背后的代码:
using System.Windows.Controls;
using StudentManagement.ViewModel;

namespace StudentManagement.Views
{
    /// <summary>
    /// Interaction logic for StudentsView.xaml
    /// </summary>
    public partial class StudentsView : UserControl
    {
        private StudentViewModel _viewModel = new 
StudentViewModel();

    public StudentsView()
    {
            InitializeComponent();
            DataContext = _viewModel;
        }

        private void cmbStatus_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string combotext = ((sender as ComboBox).SelectedItem as ComboBoxItem).Content as string;   
            string qry = @"<View>  
                        <Query> 
                            <Where><Eq><FieldRef Name='Current_x0020_Status' /><Value Type='Choice'>" + combotext + @"</Value></Eq></Where> 
                        </Query> 
                       </View>";

            _viewModel.LoadStudents(qry);

        }
    }
}

就目前而言,学生们在加载时就可以很好地加载到数据网格中。当事件 cmbStatus_SelectionChanged 触发时,我已经完成了测试,我可以看到 LoadStudents 函数触发并返回正确数量的条目,但数据网格上没有任何更新。

我确定这是一个菜鸟错误,我错过了一些基本的东西,但这个是我的头脑,我很感激任何指导。

最佳答案

由于StudentViewModel.LoadStudents()更改 Students 的值属性, View 模型需要通知 View 这发生了变化。你可以通过 StudentViewModel 来做到这一点。实现INotifyPropertyChanged (就像 Student 一样)。 DataGrid将订阅 PropertyChanged事件,并在该事件被触发时更新其内容。

关于c# - 当 ViewModel 改变时如何让 View 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56060843/

相关文章:

mvvm - MVVM,UWP和模板10- View 技术的模型独立性

wpf - 对话wpf的MVVM定位

c# - asp.net mvc 模型与(数据库映射)对象相同吗?

c# - 如何使用 MSTest 从命令行运行 SpecFlow 场景?

c# - 是否可以使用带有附加事件的 Microsoft.Xaml.Behaviors.EventTrigger 来调用命令?

c# - WPF:ContentPresenter 上的 TextTrimming

.net - 如何创建动画后启动的 EventSetter

c# - 为什么 CopyFileEx 的 FileUtilities.CopyFile 包装器会干扰 winforms?

c# - 在 C# 中调用类的 protected 构造函数

mvvm datagrid 无法从 View 更新模型