Как заставить View обновляться при изменении ViewModel - PullRequest
0 голосов
/ 09 мая 2019

Я создаю приложение 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 запускает и возвращает правильное количество записей, но в сетке данных ничего не обновляется.

Я уверен, что это ошибка новичка, и я упускаю что-то простое, но этот делает мою голову, и я был бы признателен за любое руководство.

Ответы [ 2 ]

2 голосов
/ 09 мая 2019

Вы инициализируете свою коллекцию учеников каждый раз, если выбор ComboBox изменился.

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

Вы не должны делать это со связанной коллекцией во ViewModel. Вы можете очистить коллекцию и добавить новые элементы, как это.

public class StudentViewModel
{
    public ObservableCollection<Student> Students { get; set; } = new ObservableCollection<Student>();

    public void LoadStudents(string query)
    {
        Students.Clear();

        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"] });
        }
    }
}
2 голосов
/ 09 мая 2019

Поскольку StudentViewModel.LoadStudents() изменяет значение свойства Students, модель представления должна уведомить представление, что это изменилось.Вы можете сделать это с помощью StudentViewModel для реализации INotifyPropertyChanged (точно так же, как Student).DataGrid подпишется на событие PropertyChanged и обновит его содержимое при запуске этого события.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...