2

I am working on WPF, MVVM C# simple app for learning.

I do have my front-end having Table kind of structure using element ""

See "VehicalForm.xaml" below.

Below is code of my View as well as View-Model part. (I have given just necessary files. Please let me know if you need any other files)

App.xaml.cs

using Seris.ViewModels;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;

namespace Seris
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
    public void OnStartup(object sender, StartupEventArgs e)
    {
        VehicalForm vehicalForm = new VehicalForm();
        vehicalForm.DataContext = new VehicalMainViewModel();
        vehicalForm.Show();
    }
}
}

VehicalForm.xaml

<Window x:Class="Seris.VehicalForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<WrapPanel Orientation="Vertical" Margin="10 " >
<Label Content="Vehical No" HorizontalAlignment="Left"/>
<TextBox Name="VehicalNo_Text" Height="23" TextWrapping="Wrap" Text="TextBox"  HorizontalAlignment="Left"/>
<Label Content="Model" HorizontalAlignment="Left"/>
<TextBox Name="Model_Text" Height="23" TextWrapping="Wrap" Text="TextBox" HorizontalAlignment="Left" />
<Label Content="Manufacturing Date" HorizontalAlignment="Left"/>
<DatePicker/>
<Label Content="IU No" HorizontalAlignment="Left"/>
<TextBox Height="23" Name="IUNO_Text" TextWrapping="Wrap" Text="TextBox" HorizontalAlignment="Left"/>
<Label Content="Personnel" HorizontalAlignment="Left"/>
<ComboBox Name="Personnel_Combo" HorizontalAlignment="Left" Width="116"/>
<Separator Height="20" RenderTransformOrigin="0.5,0.5" Width="16"/>
<Button Name="Save_Button" Command="{Binding SaveToList}" Content="Save" Width="66"/>
<ListView Height="294" Width="371" >
    <ListView Height="294" Width="371" ItemsSource="{Binding listItems, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" >
          <ListView.View>
            <GridView>
                <GridViewColumn Header="Vehical No" DisplayMemberBinding="{Binding VehicalNo}" />
                <GridViewColumn Header="Model" DisplayMemberBinding="{Binding Model}" />
                <GridViewColumn Header="ManufacturingDate" DisplayMemberBinding="{Binding ManufacturingDate}" />
                <GridViewColumn Header="IUNo" DisplayMemberBinding="{Binding IUNo}" />
                <GridViewColumn Header="Personnel" DisplayMemberBinding="{Binding Personnel}" />
            </GridView>
        </ListView.View>
    </ListView>
</WrapPanel> 

VehicalForm.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Seris
{

public partial class VehicalForm : Window
{
public VehicalForm()
{
    InitializeComponent();
}


}
}

VehicalMainViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Seris.Models;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Seris.Commands;
using Seris.ViewModels;

namespace Seris.ViewModels
{
public class VehicalMainViewModel : ObservableObject
{
ObservableCollection<VehicalModel> listItems = new ObservableCollection<VehicalModel>();

    #region Getter-Setter
    private string _VehicalNo;

    public string VehicalNo 
    {
        get { return _VehicalNo; }
        set
        {
            if (value != _VehicalNo)
            {
                _VehicalNo = value.Trim();
                if(OnPropertyChanged("VehicalNo"))
                    listItems.Add(new VehicalModel(VehicalNo, Model, ManufacturingDate, IUNo, PersonnelName));
            }
        }
    }
    private string _Model;

    public string Model
    {
        get { return _Model; }
        set
        {
            if (value != _Model)
            {
                _Model = value.Trim();
                OnPropertyChanged("Model");
            }
        }
    }
    private DateTime _ManufacturingDate;

    public DateTime ManufacturingDate
    {
        get { return _ManufacturingDate; }
        set
        {
            if (value != _ManufacturingDate)
            {
                _ManufacturingDate = value;
                OnPropertyChanged("ManufacturingDate");
            }
        }
    }
    private string _IUNo;

    public string IUNo
    {
        get { return _IUNo; }
        set
        {
            if (value != _IUNo)
            {
                _IUNo = value.Trim();
                OnPropertyChanged("IUNo");
            }
        }
    }
    private string _PersonnelName;

    public string PersonnelName
    {
        get { return _PersonnelName; }
        set
        {
            if (value != _PersonnelName)
            {
                _PersonnelName = value.Trim();
                OnPropertyChanged("PersonnelName");
            }
        }
    } 
    #endregion

    private ICommand _saveButton_Command;

    public ICommand SaveButton_Command
    {
        get { return _saveButton_Command; }
        set { _saveButton_Command = value; }
    }

    public void SaveToList(object o1)
    {
        listItems.Add(new VehicalModel(VehicalNo,Model,ManufacturingDate,IUNo,PersonnelName));
    }
    public void RemoveFromList()
    {

    }
    public VehicalMainViewModel()
    {
        VehicalModel vm=new VehicalModel();
        SaveButton_Command = new RelayCommand(new Action<object>(SaveToList));
    }
}
}

ObservableObject.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;

namespace Seris.Models
{
public abstract class ObservableObject: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool OnPropertyChanged(string propertyName)
    {

        this.VerifyPropertyName(propertyName); 

        PropertyChangedEventHandler handler = PropertyChanged;

        if(handler!=null)
        {
            if (propertyName != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
                return true;

            }
        }
        return false;
    }

    public void VerifyPropertyName(string propertyName)
    {
        if(TypeDescriptor.GetProperties(this)[propertyName]==null)
        {
            string msg = "Invalid Property Name: " + propertyName;

            if (this.ThrowOnInvalidPropertyName)
                throw new Exception(msg);
            else
                Debug.Fail(msg);
        }
    }

    public bool ThrowOnInvalidPropertyName { get; set; }
}
}

VehicalModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Seris.Models
{
public class VehicalModel : ObservableObject
{
    #region Getter-Setter
    private string _VehicalNo;

    public string VehicalNo 
    {
        get { return _VehicalNo; }
        set
        {
            if (value != _VehicalNo)
            {
                _VehicalNo = value.Trim();
                OnPropertyChanged("VehicalNo");
            }
        }
    }
    private string _Model;

    public string Model
    {
        get { return _Model; }
        set
        {
            if (value != _Model)
            {
                _Model = value.Trim();
                OnPropertyChanged("Model");
            }
        }
    }
    private DateTime _ManufacturingDate;

    public DateTime ManufacturingDate
    {
        get { return _ManufacturingDate; }
        set
        {
            if (value != _ManufacturingDate)
            {
                _ManufacturingDate = value;
                OnPropertyChanged("ManufacturingDate");
            }
        }
    }
    private string _IUNo;

    public string IUNo
    {
        get { return _IUNo; }
        set
        {
            if (value != _IUNo)
            {
                _IUNo = value.Trim();
                OnPropertyChanged("IUNo");
            }
        }
    }
    private string _PersonnelName;

    public string PersonnelName
    {
        get { return _PersonnelName; }
        set
        {
            if (value != _PersonnelName)
            {
                _PersonnelName = value.Trim();
                OnPropertyChanged("PersonnelName");
            }
        }
    } 
    #endregion

    #region Constructor
    public VehicalModel(string VehicalNo, string Model, DateTime ManufacturingDate, string IUNo, string PersonnelName)
    {
        this.VehicalNo = VehicalNo;
        this.Model = Model;
        this.ManufacturingDate = ManufacturingDate;
        this.IUNo = IUNo;
        this.PersonnelName = PersonnelName;

    }
    public VehicalModel()
    {
        this.VehicalNo = null;
        this.Model = null;
        this.ManufacturingDate = DateTime.Now;
        this.IUNo = null;
        this.PersonnelName = null;

    } 
    #endregion

    #region Methods

    #region Validate Methods

    public bool Validate_VehicalNo()
    {
        if (matchRE(VehicalNo,"[A-Zz-z][A-Zz-z0-9]{6}"))
            return true;
        else
            return false;
    }
    public bool Validate_Model()
    {
        if(Model!=null)
            return true;
        else
            return false;
    }
    public bool Validate_ManufacturingDate()
    {
        return true;
    }
    public bool Validate_IUNo()
    {
        if(matchRE(IUNo,"[0-9]{10}"))
            return true;
        else
            return false;
    }
    public bool Validate_PersonnelName()
    {
        if(matchRE(PersonnelName,"[A-Za-z]+"))
            return true;
        else
            return false;

    }  

    public bool matchRE(string stringToMatch, string regularExpression)
    {
        Regex regex = new Regex(@regularExpression);
        Match match = regex.Match(stringToMatch);

        if(match.Success)
            return(true);
        else
            return(false);
    }
    #endregion

    #endregion
}
}

What I need is

1) When I update VehicalNo, new row should be added in the table.

2) If I need to update individual elements of every row in future which should reflect in table as soon as I update , is there inbuilt facility in ListView? Or I need to use List for individual elements (i.e. VehicalNo, Model, ... ) and put in one main List keeping eye using ObservableObject? I don't know eventhough it is being added to list as well as I have implemented INotifyPropert using ObservableObject, why its not reflecting in front-end.

Please help.

Pratik
  • 161
  • 4
  • 13
  • 1
    You need to set the `DataContext` of your VehicalForm.xaml to the ViewModel. and also bind the `ItemSource` of the ListView to the List you would like to display (e.g. `ObservableCollection listItems`). Then Bind each Individual Column in that listview to a property of `VehicalModel` – JKennedy Aug 01 '14 at 07:33
  • [See here for more details](http://stackoverflow.com/questions/17003998/simple-listview-data-binding) – JKennedy Aug 01 '14 at 07:34
  • user1: I have already set DataContext properly. Also edited my code again by Binding to lostItems. Kindly check the question again and if not proper please let me know how to bind individual property of ListView to a property of VehicalModel. – Pratik Aug 01 '14 at 07:38
  • I can see the problem. When binding to `listItems` each row in the ListView gets the datacontext of that individual Item. In this example each row gets a datacontext of `VehicalModel` (it would help to post this class) therefore the program is trying to find the properties, VehicalNo, Model etc. on your `VehicalModel` class. Where I doubt they exist. in your output window you will probably see a binding error saying the property VehicalNo could not be found on object VehicalModel – JKennedy Aug 01 '14 at 07:49
  • user1: I updated. Also request to please explain this dataContext issue simply, as I am beginner. – Pratik Aug 01 '14 at 07:51

2 Answers2

2

Add public ObservableCollection ListItems {get{return listItems;}}

to you VehicalMainViewModel and change binding to ItemsSource="{Binding ListItems}"

P.S. your listItems is private field.

Famos
  • 261
  • 4
  • 13
  • This is a good observation. I missed this bug. I would suggest @pratik looked at the output window for clues to the erros – JKennedy Aug 01 '14 at 08:42
  • My dear friend you are great....! :) Because of less reputation can't give +1 but Special virtual like from my side. :P Muaah... – Pratik Aug 01 '14 at 08:43
  • Would you please answer for my 2nd question? That is also very important for me. – Pratik Aug 01 '14 at 08:49
0

ok so heres an example of the first Text box and you can follow suit on the rest:

<Window x:Class="Seris.VehicalForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:Seris.ViewModels"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <local:VehicalMainViewModel/>
</Window.DataContext>
<Label Content="Vehical No" HorizontalAlignment="Left"/>
<TextBox Name="VehicalNo_Text" Height="23" TextWrapping="Wrap" Text="{Binding VehicalNo}"  HorizontalAlignment="Left"/>

I cannot find any references at the moment but I would suggest looking at DataContext and Data Binding in WPF

EDIT

<Application x:Class="Seris.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="VehicalForm.xaml">
    <Application.Resources>

    </Application.Resources>
</Application>
JKennedy
  • 18,150
  • 17
  • 114
  • 198
  • For your reference I have kept DataContext File also. Now see whole question and please tell me whats remaining? Still output is not coming. – Pratik Aug 01 '14 at 08:10
  • @Pratik I would say rather than the `Startup` method in the App Code behind I would put a startup URi in the App.Xaml see Edit For Details – JKennedy Aug 01 '14 at 08:23
  • It doesn't matter. Code is already running and I have already worked on both in the past. Please find the remaining bug asap so that I can give you correct answer. – Pratik Aug 01 '14 at 08:26