Элемент, добавленный в ObservableCollection в ViewModel, не отображается

Довольно новичок в мире WPF. Я уже несколько дней болею за глаза, ища решение, но не удалось сделать все правильно.

То, что я пытаюсь достичь:

  • Создайте ObservableCollection в классе модели представления
  • Свяжите данные внутри файла .xaml
  • Создайте кнопку «Добавить» из частного void Button_Click в MainWindow.xaml.cs (я буду создавать команды позже - мне просто нужно сделать это шаг за шагом и упростить понимание процесса).

Кажется довольно простым, мм? Мне удалось сделать все это в MainWindow.xaml.cs (только с использованием ObservableCollection, no 'PropertyChanged'), но я не могу заставить его работать в ViewModel.

Теперь мой код:  

Client.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataBindingTestInViewModel
{
    class Client
    {
        protected string _firstName;
        protected string _name;

        public string FirstName
        {
            get { return _firstName; }
            set { _firstName = value; }
        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
    }
}

MainWindow.xaml

<Window x:Class="DataBindingTestInViewModel.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:DataBindingTestInViewModel"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <ItemsControl Grid.Row="0" ItemsSource="{Binding Clients}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Label Grid.Column="0" Content="{Binding FirstName}" />
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

        <Button Grid.Row="1" Click="Button_Click">Add a client</Button>
    </Grid>
</Window>

MainWindow.xaml.cs (создайте экземпляр события ViewModel + Button_Click)

using System.Windows;

namespace DataBindingTestInViewModel
{
    /// <summary>
    /// Logique d'interaction pour MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        ViewModel viewmodel = new ViewModel();

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            viewmodel.AddClient();
        }
    }
}

ViewModel.cs

using System.Collections.ObjectModel;
using System.Windows;

namespace DataBindingTestInViewModel
{
    class ViewModel
    {
        private ObservableCollection<Client> _clients = new ObservableCollection<Client>();

        public ViewModel()
        {
            _clients.Add(new Client() { FirstName = "John", Name = "Doe" });
            _clients.Add(new Client() { FirstName = "Jane", Name = "Doe" });
            //MessageBox.Show("Constructeur du View Model appele.");
        }
        public ObservableCollection<Client> Clients
        {
            get { return _clients; }
        }

        public void AddClient()
        {
            _clients.Add( new Client() { FirstName = "Donald", Name = "Trump" } );
            MessageBox.Show("First element : " + _clients[0].FirstName + "
" +
                            "Third element : " + _clients[2].FirstName );

        }
    }
}

Результаты :

  • Отображаются «John Doe / Jane Doe»
  • Когда я нажимаю кнопку, она не добавляет ничего в пользовательский интерфейс. (Но Messagebox отлично работает.)

То, что я думаю, происходит:

Контекст данных MainWindow привязан к экземпляру клиента ViewModel. Я создаю и добавляю элемент в новый экземпляр, вызываемый в MainWindow, - и это не тот, который используется в datacontext.

Вопросов :

  • Я прав ? Если да, то как его решить (вызовите метод AddClient экземпляра Viewmodel в MainWindow)?
  • Любые другие (но простые, пожалуйста!) Методы?

Думаю, это будет кусок пирога для тебя. Спасибо !!

c#,wpf,mvvm,observablecollection,

0

Ответов: 1


1 принят

вы правы в работе с 2 экземплярами (один из них создан в xaml, а другой - в коде). есть 2 способа исправить ситуацию.

работа с экземпляром, созданным в xaml. чтобы получить ссылку на этот экземпляр, введите DataContext в тип vm:

public partial class MainWindow : Window
{
    ViewModel viewmodel;

    public MainWindow()
    {
        InitializeComponent();
        viewModel = (ViewModel)DataContext;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        viewmodel.AddClient();
    }
}

работа с экземпляром, созданным в коде. также установите DataContext из кода:

public partial class MainWindow : Window
{
    ViewModel viewmodel = new ViewModel();

    public MainWindow()
    {
        InitializeComponent();
        DataContext = viewmodel;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        viewmodel.AddClient();
    }
}

и удалите часть xaml:

<Window.DataContext>
    <local:ViewModel />
</Window.DataContext>
C #, WPF, MVVM, ObservableCollection,
Похожие вопросы