更改ViewModel后如何更新View

时间:2019-05-09 13:45:01

标签: c# wpf mvvm

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

这是我的模特:

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));
        }
    } 
  }
}

这是视图模型:

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>

...以及该视图后面的代码:

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函数触发并返回正确数量的条目,但是在datagrid上没有任何更新。

我确定这是一个菜鸟错误,并且我遗漏了一些基本知识,但是我正在努力,我会很感激任何指导。

2 个答案:

答案 0 :(得分:2)

由于StudentViewModel.LoadStudents()更改了Students属性的值,因此视图模型需要通知该更改。您可以通过让StudentViewModel实现INotifyPropertyChanged来实现此目的(就像Student一样)。 DataGrid将订阅PropertyChanged事件,并在触发该事件时更新其内容。

答案 1 :(得分:2)

如果组合框的选择发生更改,则每次都在初始化学生集合。

SparkSession

您不应在ViewModel中使用绑定集合来执行此操作。您可以清除集合并添加新的项目。

<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8">
   </head>
   <body>
      <select id='site'>
         <option>Choose site</option>
         <option value="#">Google</option>
         <option value="#">Apple</option>
         <option value="#">Amazon</option>
      </select>
      <select id='format' onchange="myFunction()">
         <option>Choose format</option>
         <option value="#">Mobile</option>
         <option value="#">Desktop</option>
         <option value="#">Tablet</option>
      </select>
      <script>
         function myFunction() {
            var site = document.getElementById("site");
             var format = document.getElementById("format");

             if(site.selectedIndex == 0) {
                alert('Please choose a site');
                 return 0;
             }

             var location = site[site.selectedIndex].text;
             location += ".com/?demo="
             location += format[format.selectedIndex].text;

             alert(location)
         }

      </script>
   </body>
</html>