0
votes

I try to figure out how MVVM works and want to start simple.

I made a Model, a View and a ViewModel. I hooked up the view to a window. this works more or less. in the view i have a textbox which i want to fill with the value of a property. The textbox keeps empty!?

This is what i have: Model:

namespace Qbox_0001.Model
{
    public class RegistratieModel
    {
    }

    public class Registratie : INotifyPropertyChanged
    {

        //Fields
        private string programmaNaam;

        //eventhandler die kijkt of een property wijzigt
        public event PropertyChangedEventHandler PropertyChanged;

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

        //Properies
        public string ProgrammaNaam
        {
            get { return programmaNaam; }
            set
            {
                if (programmaNaam != value)
                {
                    programmaNaam = value;
                    RaisePropertyChanged("ProgrammaNaam");
                }
            }
        }

    }
}

The View:

<UserControl x:Name="UserControlRegistratie" x:Class="Qbox_0001.Views.RegistratieView"
             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" 
             xmlns:local="clr-namespace:Qbox_0001.Views"
             mc:Ignorable="d" Height="1000" Width="860" MaxWidth="860" HorizontalContentAlignment="Left" VerticalContentAlignment="Top">
    <Grid x:Name="GridRegistratie">


        <Grid.RowDefinitions>
            <RowDefinition x:Name="RowDef_Menu" Height="21*" MaxHeight="21" MinHeight="21"/>
            <RowDefinition x:Name="RowDef_TabControl" Height="500*" MinHeight="500"/>
            <RowDefinition x:Name="Rowdef_Bottom" Height="40*" MaxHeight="40" MinHeight="40"/>
        </Grid.RowDefinitions>

        <Grid x:Name="Grid_Registratie_WorkArea" Grid.Row="1">

            <TabControl x:Name="TabControl_Registratie">
                <TabItem Header="Registratie">
                    <Grid x:Name="Grid_Tab_Registratie">
                        <Border>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition x:Name="GridRowDef_Algemeen" MinHeight="68" Height="68*" MaxHeight="68"/>
                                    <RowDefinition x:Name="GridRowDef_Locatie"  MinHeight="120" Height="120*" MaxHeight="120"/>
                                    <RowDefinition x:Name="GridRowDef_AantalDagen" MinHeight="105" Height="105*" MaxHeight="105"/>
                                    <RowDefinition x:Name="GridRowDef_MaxDagen" MinHeight="105" Height="105*" MaxHeight="105"/>
                                    <RowDefinition x:Name="GridRowDef_Lokaal" MinHeight="100" Height="100*" MaxHeight="100"/>
                                    <RowDefinition x:Name="GridRowDef_LicBestand" Height="150*" MaxHeight="150" MinHeight="150"/>
                                </Grid.RowDefinitions>

                                <GroupBox x:Name="GroupBox_algemeen" Header="Algemeen" Margin="10,4,10,3">
                                    <Grid>
                                        <Label x:Name="Label_Klant" Content="Klant:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Padding="0,5,5,5"/>
                                        <Label x:Name="Label_Programma" Content="Programma:" HorizontalAlignment="Left" Margin="356,10,0,0" VerticalAlignment="Top"/>
                                        <Label x:Name="Label_Versie" Content="Versie:" HorizontalAlignment="Left" Margin="645,10,0,0" VerticalAlignment="Top"/>
                                        <TextBox x:Name="textBox_KlantNaam" HorizontalAlignment="Left" Height="23" Margin="49,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="288"/>

                                        <!-- the textbox keeps empty -->
                                        <TextBox x:Name="TextBox_ProgrammaNaam" Text="{Binding ElementName=RegistratieViewModel, Path=ProgrammaNaam, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Height="23" Margin="431,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="190" IsEnabled="False" />


                                        <TextBox x:Name="TextBox_Versie" HorizontalAlignment="Left" Height="23" Margin="695,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" IsEnabled="False" />

                                    </Grid>
                                </GroupBox>

                            </Grid>
                        </Border>
                    </Grid>
                </TabItem>
                <TabItem Header="Licentie(s)">
                    <Grid x:Name="Grid_Tab_Licentie" Background="#FFE5E5E5"/>
                </TabItem>
            </TabControl>
        </Grid>

    </Grid>
</UserControl>

In the View.cs:

namespace Qbox_0001.Views
{
    /// <summary>
    /// Interaction logic for RegistratieView.xaml
    /// </summary>
    public partial class RegistratieView : UserControl
    {
        public RegistratieView()
        {
            InitializeComponent();
            this.DataContext = new Qbox_0001.ViewModel.RegistratieViewModel();
        }
    }
}

The ViewModel

using Qbox_0001.Model;                  //
using System.Collections.ObjectModel;   //


namespace Qbox_0001.ViewModel
{
    public class RegistratieViewModel
    {
        public RegistratieViewModel()
        {
            loadRegistratieOnderdelen();
        }

        public ObservableCollection<Registratie> RegistratieOnderdelen  //Registratie = "public class Registratie : INotifyPropertyChanged" van de Model
        {
            get;
            set;
        }

        public void loadRegistratieOnderdelen()
        {
            ObservableCollection<Registratie> regOnderdelen = new ObservableCollection<Registratie>();

            regOnderdelen.Add(new Registratie { ProgrammaNaam = "Test" });

        }
    }
}
2

2 Answers

0
votes

I can see a couple of problems with your code.

You are populating a local ObservableCollection (inside your loadRegistratieOnderdelen() method) with data but since its local, it is not a member of the DataContext and hence unavailable to the View. You have to use public properties like RegistratieOnderdelen which you already declared in your RegistratieViewModel.

Next you are using an ObservableCollection whereas you might just want to use a property of type String. Collections are used when you want to represent lists, for example inside a ListView or an ItemsControl. Your view indicates that you want to bind a single text value so a public property of type String makes more sense.

Best, Nico

0
votes

The DataContext is a RegistratieViewModel. This class has a RegistratieOnderdelen property that returns a collection of Registratie objects.

You could bind to the ProgrammaNaam property of one such item but you need to specify which item to bind to, for example the first one:

<TextBox x:Name="TextBox_ProgrammaNaam" Text="{Binding Path=RegistratieOnderdelen[0].ProgrammaNaam, UpdateSourceTrigger=PropertyChanged}" ... />