С# MVVM WPF Добавление и удаление в DateGrid

149
27 ноября 2018, 05:10

View

    <Window x:Class="Person_Changed.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Person_Changed"
            xmlns:human="clr-namespace:Person_Changed.ViewModel"
            mc:Ignorable="d"
            Title="MainWindow" Height="355.263" Width="493.421">
        <Window.DataContext>
            <human:HumanViewModel/>
        </Window.DataContext>
        <Grid Margin="0,0,2,-5">
            <ListView 
                x:Name="listView"
                ItemsSource="{Binding Humans }"
                Margin="10,122,10,10">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Ид"      DisplayMemberBinding="{Binding Id}"         Width="60" />
                        <GridViewColumn Header="Имя"     DisplayMemberBinding="{Binding FirstName}"  Width="70" />
                        <GridViewColumn Header="Фамилия" DisplayMemberBinding="{Binding SurName}"    Width="80" />
                        <GridViewColumn Header="Паспорт" DisplayMemberBinding="{Binding Passport}"   Width="100" />
                        <GridViewColumn Header="Дата"    DisplayMemberBinding="{Binding DataBirth}"  Width= "150" />
                    </GridView>
                </ListView.View>
            </ListView>
            <Button  
                Content="Добавить"
                HorizontalAlignment="Left"
                Margin="161,0,0,283"
                Width="84"
                Command="{Binding AddHuman}"
                BorderThickness="0" Height="36" VerticalAlignment="Bottom"/>
            <TextBox  HorizontalAlignment="Left" Height="20" Text="{Binding FirstName,  UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120" Margin="10,10,0,0"/>
            <TextBox  HorizontalAlignment="Left" Height="20" Text="{Binding SurName,    UpdateSourceTrigger=PropertyChanged}"   VerticalAlignment="Top" Width="120" Margin="10,38,0,0"/>
            <TextBox  HorizontalAlignment="Left" Height="20" Text="{Binding Passport,   UpdateSourceTrigger=PropertyChanged}"  VerticalAlignment="Top" Width="120" Margin="10,66,0,0"/>
            <DatePicker HorizontalAlignment="Left" Height="20" Text="{Binding DataBirth,   UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Margin="10,93,0,0" Width="120" FontSize="10" FontFamily="Times New Roman"/>
            <Button  
                Content="Удалить"
                HorizontalAlignment="Left"
                Margin="161,0,0,230"
                Width="84"
                BorderThickness="0" Height="36" VerticalAlignment="Bottom"/>

        </Grid>
    </Window>

Human

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using GalaSoft.MvvmLight;
namespace Person_Changed.Model
{
    public class Human : ObservableObject
    {
        private int _id;
        private string _firstname;
        private string _surname;
        private string _passport;
        private DateTime _databirth;

        #region property
        public int Id
        {
            get { return _id; }
            set
            {
                _id = value;
                RaisePropertyChanged(() => Id);
            }
        }
        public string FirstName
        {
            get { return _firstname; }
            set
            {
                _firstname = value;
                RaisePropertyChanged(() => FirstName);
            }
        }
        public string SurName
        {
            get { return _surname; }
            set
            {
                _surname = value;
                RaisePropertyChanged(() => SurName);
            }
        }
        public string Passport
        {
            get { return _passport; }
            set
            {
                _passport = value;
                RaisePropertyChanged(() => Passport);
            }
        }
        //[DisplayFormat(DataFormatString ="{0:dd'/'MM'/'yyyy}",ApplyFormatInEditMode =true)]
        public DateTime DataBirth
        {
            get { return _databirth; }
            set
            {
                _databirth = value;
                RaisePropertyChanged(() => DataBirth);
            }
        }
        #endregion
    }
}

HumanViewModel

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Person_Changed.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace Person_Changed.ViewModel
{
    class HumanViewModel : ViewModelBase
    {
        public ObservableCollection<Human> Humans { get; set; }
        private Human _selectedhuman;
        public Human SelectedHuman
        {
            get { return _selectedhuman; }
            set
            {
                _selectedhuman = value;
                RaisePropertyChanged(() => SelectedHuman);
            }
        }
        public HumanViewModel()
        {
            DateTime newdate = new DateTime(2018, 01, 01);
            Humans = new ObservableCollection<Human>
            {
                new Human {Id = 1, FirstName="Иван", SurName = "Иванов", Passport = "1111-111111", DataBirth = newdate}
            };
        }
        private ICommand _addhuman;
        public ICommand AddHuman
        {
            get
            {
                return _addhuman ?? (_addhuman = new RelayCommand(() => 
                {
                    Human human = new Human();
                    Humans.Add(human);
                }));
            }
        }
    }
}

Цель - Добавить значение в коллекцию DataGrid из textbox'ов

У меня почему-то не перехватывается биндинги полей и заполняется нулями

Answer 1

Смотрите, тут все очень просто! Вы на "холсте" размещаете ListView, пару Button, несколько TextBox и DatePicker. Отлично, все они ожидают свое свойство в указанном как DataContext классе. Смотрим, какой класс мы указали:

<Window.DataContext>
    <human:HumanViewModel/>
</Window.DataContext>

HumanViewModel - это наша главная ViewModel, на нее все ссылаются.

Хорошо, пойдем дальше, пройдемся по всем нашим объектам на холсте и сравним с тем, что есть в главной VM:

  • ListView - данный контрол ожидает в ItemsSource коллекцию, вы указываете Humans, смотрим в главную VM и действительно, видим ее там public ObservableCollection<Human> Humans { get; set; }.
    • Внутри ListView вы задаете GridViewColumn - эти объекты будут брать за главную VM тот объект, который лежит внутри коллекции (у вас это <Human>).
  • Button - в роди команды ожидает свойство типа ICommand, вы указываете AddHuman, проверяем и да, опять находим: public ICommand AddHuman.
  • TextBox - Text, это string значение, а значит ищем string свойство в нашей HumanViewModel, вы привязываете это все к FirstName, ищем и его в VM нету, а значит этому текстовому полю уже попросту не к чему привязываться.

Напомню, что все объекты привязываются к свойствам из класса, который задан как DataContext!

Надеюсь с этим мы разобрались. Теперь посмотрим на кнопку добавления, вы там делаете следующее:

Human human = new Human();
Humans.Add(human);

То есть вы берете, создаете новый, пустой объект Human и добавляете его (пустой) в коллекцию. Что то вы тут забыли, заполнение? Не удивительно, что вы видите пустые объекты!

Теперь как это все решить:

  • Как вариант, это создать все свойства для TextBox'ов (Id, FirstName, SurName, Passport, DataBirth) в главной ViewModel и при добавление указывать их значения.
  • Еще вариант, это создание отдельного свойства (public Human SelectedHuman {get;set;} = new Human();), которое будет использоваться для TextBox'ов ({Binding SelectedHuman.Id}), а также для выделенного элемента самого ListView (SelectedItem="{Binding SelectedHuman}"). Добавление тогда у вас будет простое Humans.Add(SelectedItem);, да и удаление тоже (Humans.Remove(SelectedItem);).

Подытожив все это, имеем две проблемы:

  1. Привязка к несуществующим свойствам.
  2. Добавление пустого объекта в коллекцию.

В общем удачи в изучении WPF!

READ ALSO
Почему не меняется Effect Distance в Shadow unity3d

Почему не меняется Effect Distance в Shadow unity3d

Навесил метод на кнопку, но при нажатии ничего не происходит, остаются прежние значения, почему?

180
Проверка на отсутствие одинаковых TabPage`ов

Проверка на отсутствие одинаковых TabPage`ов

Мне необходимо проверить все TabPage`ы в TabControl, и если среди них не был найден ни один с определенным текстом, то выполнять на определенное действие

149
Как сделать синхронную анимацию на Unity 3D

Как сделать синхронную анимацию на Unity 3D

Я делаю игру Match3 на unity (C#)Мне нужно синхронизировать анимацию отдельных элементов в Unity (C#), при выделение одно элемента анимация включается...

155
Dictionary in C# [закрыт]

Dictionary in C# [закрыт]

Как можно Dictionary вывести в виде?:

140