Binding items into ListBox multiple columns - c#

I am trying to add my data into multiple columns ListBox, I did it but I am facing a hard problem when trying to retrieve the Data from the list box. is there a way to put an object instead of text into a listBox row?
<ListView Name="listBox1" ItemsSource="{Binding Items}" Margin="28,28,68,67" FlowDirection="RightToLeft" MouseDoubleClick="listBox1_MouseDoubleClick">
<ListView Name="listBox1" ItemsSource="{Binding Items}" Margin="28,28,68,67" FlowDirection="RightToLeft" MouseDoubleClick="listBox1_MouseDoubleClick">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="a" Width="100" DisplayMemberBinding="{Binding Path=ID}" />
<GridViewColumn Header="b" Width="100" DisplayMemberBinding="{Binding Path=Name}" />
<GridViewColumn Header="c" Width="100" DisplayMemberBinding="{Binding Path=F}" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
</Grid>
and this is the code
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public sealed class MyListBoxItem
{
public string Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Students st = new Students(1, "name","anything");
listBox1.ItemsSource = new List(new[] { st });
}
private void listBox1_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
object ob = listBox1.SelectedItem;
string i = ((MyListBoxItem)listBox1.SelectedItem).Field1;
}
}
and here is the class Students
class Students
{
int id;
string name;
string f;
public Students(int id, string name,string f)
{
this.id = id;
this.name = name;
this.f = f;
}
public int ID
{
get { return id; }
set { id = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public string F
{
get { return f; }
set { f = value; }
}
}

Don't use listBox1.Items.Add(....). Rather use listBox1.ItemsSource = new List(new[] {st});
Then change Your DisplayMemberBindings to "Id", "Name" respectively.
There is no need for the ListBoxItem Class.
== EDIT ==
You were very close to getting it perfectly. I've attached below how it should work. The important things to notice are the Bindings in the ListView for ItemsSource and SelctedITem, and setting IsSynchronisedWithCurrentItem to true.
Also, in the bottom two rows ofthe grid, I've shown two different ways of binding to the selected item, one using "/" notation, and the other using a property on the ViewModel
XAML
<Window x:Class="StackOverflow11087468.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView Name="listBox1"
Grid.Row="0"
ItemsSource="{Binding Students}"
SelectedItem="{Binding SelectedStudent}"
IsSynchronizedWithCurrentItem="True"
Margin="28,28,68,67"
FlowDirection="RightToLeft">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="a"
Width="100"
DisplayMemberBinding="{Binding Path=ID}" />
<GridViewColumn Header="b"
Width="100"
DisplayMemberBinding="{Binding Path=Name}" />
<GridViewColumn Header="c"
Width="100"
DisplayMemberBinding="{Binding Path=F}" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<TextBlock>ID</TextBlock>
<TextBox Text="{Binding Students/ID}" />
</StackPanel>
<StackPanel Grid.Row="2"
Orientation="Horizontal">
<TextBlock>ID</TextBlock>
<TextBox Text="{Binding SelectedStudent.ID}" />
</StackPanel>
</Grid>
</Window>
Main.Window.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 StackOverflow11087468
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new ViewModel();
}
}
}
ViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace StackOverflow11087468
{
public class ViewModel : INotifyPropertyChanged
{
public ObservableCollection<Student> Students { get; set; }
public ViewModel()
{
this.Students = new ObservableCollection<Student>();
Students.Add(new Student(98760987, "Student1", "F"));
Students.Add(new Student(98760988, "Student22", "M"));
}
public Student SelectedStudent
{
get { return _selectedStudent; }
set
{
_selectedStudent = value;
RaisePropertyChanged("SelectedStudent");
}
}
private void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
private Student _selectedStudent;
}
}

Related

Question about ListView binding with MVVM

I'm working on an app that has a ListView requiring a column with a checkbox. Below is an example of the XAML. IsSelected is part of the Items class, but I'm receiving the error "Cannot resolve property 'IsSelected' in data context of type 'App.ViewModel.ItemViewModel'". I do not receive any errors at runtime, but the XAML shows an error because it is looking for an IsSelected property in the ItemViewModel. If I add DataContext="{Binding Items}" I am no longer able to bind SelectedValue to SelectedItem.
Any thoughts on what I'm doing wrong or how I can restructure this in order to get it working?
<Window x:Class="App.View.AppWindow"
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:App.View"
xmlns:vm="clr-namespace:App.ViewModel"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:ui="http://schemas.modernwpf.com/2019"
mc:Ignorable="d"
Title="AppWindow" Height="800" Width="1100"
ResizeMode="CanMinimize>
<Grid DataContext="{StaticResource ItemViewModel}">
<ListView ItemsSource="{Binding Items}"
SelectedValue="{Binding SelectedItem}">
<ListView.View>
<GridView AllowsColumnReorder="true">
<GridViewColumn Header="Selected" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding ItemNumber}"
Header="Item #"
Width="80"/>
<GridViewColumn DisplayMemberBinding="{Binding TransactionCode}"
Header="Detail"
Width="200"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
Here is the declaration of Items in the ItemViewModel:
using App.Models;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows;
namespace App.ViewModel;
public class ItemViewModel : INotifyPropertyChanged
{
// Property for items
private ObservableCollection<Item>? _items;
public ObservableCollection<Item>? Items
{
get => _items;
set
{
_items = value;
OnPropertyChanged(nameof(Items));
}
}
// Property for selected item
private Item? _selectedItem;
public Item? SelectedItem
{
get => _selectedItem;
set
{
_selectedItem = value;
OnPropertyChanged(nameof(SelectedItem));
}
}
// Constructor Item ViewModel
public ItemViewModel()
{
Items = new ObservableCollection<Item>();
}
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Here is the model for Item in the Model:
namespace App.Models;
public class Item
{
public bool IsSelected { get; set; }
public string? ItemNumber { get; set; }
public string? Detail { get; set; }
}

Using Update button in WPF ListView to update Selected Item

I have to make a WPF App to add, delete and update Items for Client Management purposes. I have so far been able to add and remove the items to the List using MVVM but I am unable to update the selected items. I require help in this regard.
The code for the project is as follows:
Details Class.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment_2.Model
{
public class Details :INotifyPropertyChanged
{
private string name;
public string Name
{ get { return name; } set { name = value; OnPropertyChanged(Name); } }
private string company;
public string Company
{ get { return company; } set { company = value; OnPropertyChanged(Company); } }
private string region;
public string Region
{ get { return region; } set { region = value; OnPropertyChanged(Region); } }
private string hra;
public string HRA
{
get { return hra; }
set
{
hra = value;
OnPropertyChanged(HRA);
}
}
private string basic;
public string Basic
{ get { return basic; }
set { basic = value;
OnPropertyChanged(Basic);
}
}
private string pf;
public string PF
{ get { return pf; }
set
{
pf = value;
OnPropertyChanged(PF);
}
}
private string salary;
public string Salary
{ get { return salary; }
set
{
salary = value;
OnPropertyChanged(Salary);
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string det)
{
PropertyChangedEventHandler pc = PropertyChanged;
if (pc != null)
pc(this, new PropertyChangedEventArgs(det));
}
}
}
DetailsViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Assignment_2.Commands;
using Assignment_2.Model;
namespace Assignment_2.ViewModel
{
public class DetailsViewModel : INotifyPropertyChanged
{
private Details record;
public Details Record
{
get { return record; }
set { record = value; NotifyPropertyChanged("Record"); }
}
private ObservableCollection<Details> records;
public ObservableCollection<Details> Records
{
get { return records; }
set { records = value; } // NotifyPropertyChanged("Records");
}
private ICommand _SubmitCommand;
public ICommand SubmitCommand
{
get
{
if (_SubmitCommand == null)
{
_SubmitCommand = new RelayCommand(SubmitExecute, CanSubmitExecute, false);
}
return _SubmitCommand;
}
}
public DetailsViewModel()
{
Record = new Details();
Records = new ObservableCollection<Details>();
}
private void SubmitExecute(object parameter)
{
var TempRecord = new Details();
//TempRecord = Record;
TempRecord.Name = Record.Name;
TempRecord.Company = Record.Company;
TempRecord.Region = Record.Region;
TempRecord.HRA = Record.HRA;
TempRecord.Salary = Record.Salary;
TempRecord.Basic = Record.Basic;
TempRecord.PF = Record.PF;
Records.Add(TempRecord);
}
private bool CanSubmitExecute(object parameter)
{
if (string.IsNullOrEmpty(Record.Name) || string.IsNullOrEmpty(Record.Company))
{
return false;
}
else
{
return true;
}
}
private ICommand _SubmitCommand1;
public ICommand SubmitCommand1
{
get
{
if (_SubmitCommand1 == null)
{
_SubmitCommand1 = new RelayCommand(SubmitExecute1, CanSubmitExecute1, false);
}
return _SubmitCommand1;
}
}
public int findIndex(Details myDetails)
{
int count = 0;
for (int i = 0; i < Records.Count; i++)
{
count = 0;
Details myRecord = Records[i];
if (myRecord.Name == myDetails.Name)
count++;
else continue;
if (myRecord.Company == myDetails.Company)
count++;
else continue;
if (myRecord.Region == myDetails.Region)
count++;
else continue;
if (myRecord.Salary == myDetails.Salary)
count++;
else continue;
if (myRecord.HRA == myDetails.HRA)
count++;
else continue;
if (myRecord.Basic == myDetails.Basic)
count++;
else continue;
if (myRecord.PF == myDetails.PF)
count++;
else continue;
if (count == 7)
return i;
}
return -1;
}
private void SubmitExecute1(object parameter)
{
Records.Remove((Details)parameter);
}
private bool CanSubmitExecute1(object parameter)
{
if (string.IsNullOrEmpty(Record.Name) || string.IsNullOrEmpty(Record.Company))
{
return false;
}
else
{
return true;
}
}
private ICommand _SubmitCommand2;
public ICommand SubmitCommand2
{
get
{
if (_SubmitCommand2 == null)
{
_SubmitCommand2 = new RelayCommand(SubmitExecute2, CanSubmitExecute2, false);
}
return _SubmitCommand2;
}
}
private void SubmitExecute2(object parameter)
{
}
private bool CanSubmitExecute2(object parameter)
{
if (string.IsNullOrEmpty(Record.Name) || string.IsNullOrEmpty(Record.Company))
{
return false;
}
else
{
return true;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string de)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(de));
}
}
}
RelayCommand.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace Assignment_2.Commands
{
class RelayCommand : ICommand
{
Action<object> executeAction;
Func<object, bool> canExecute;
bool canExecuteCache;
public RelayCommand(Action<object> executeAction, Func<object, bool> canExecute, bool canExecuteCache)
{
this.canExecute = canExecute;
this.executeAction = executeAction;
canExecuteCache = canExecuteCache;
}
public bool CanExecute(object parameter)
{
if (canExecute == null)
{
return true;
}
else
{
return canExecute(parameter);
}
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
public void Execute(object parameter)
{
executeAction(parameter);
}
}
}
MainWindow.xaml
<Window x:Class="Assignment_2.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:vm="clr-namespace:Assignment_2.ViewModel"
Title="MainWindow" Height="401" Width="472">
<Window.Resources>
<vm:DetailsViewModel x:Key="DetailsViewModel"/>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource DetailsViewModel}}" RenderTransformOrigin="0.5,0.5" Margin="0,0,1,1">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-0.21"/>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="20.59"/>
<RowDefinition Height="22.906"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="29*"/>
<RowDefinition Height="293*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Text=" Name" HorizontalAlignment="Center" Margin="0,0,0,4" Grid.RowSpan="2" Width="35" />
<TextBox Grid.Column="1" Width="100" HorizontalAlignment="Left" Text="{Binding Record.Name,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Margin="2,0,0,1" Grid.RowSpan="2"/>
<TextBlock Text="Company" HorizontalAlignment="Center" Margin="0,2,0,3" Width="51" Grid.RowSpan="2" Grid.Row="1"/>
<TextBox Grid.Column="1" Width="100" HorizontalAlignment="Left" Text="{Binding Record.Company,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Margin="2,2,0,1" Grid.Row="1"/>
<TextBlock Grid.Row="2" Text="Region" HorizontalAlignment="Center" Margin="0,1,0,4" Width="37"/>
<TextBox Grid.Row="2" Grid.Column="1" Width="100" HorizontalAlignment="Left" Text="{Binding Record.Region,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Margin="3,1,0,4"/>
<TextBlock Grid.Column="1" Text="HRA" HorizontalAlignment="Left" Margin="131,-1,0,2" Width="23"/>
<TextBox Grid.Column="1" Width="83" HorizontalAlignment="Left" Text="{Binding Record.HRA,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Margin="162,0,0,1"/>
<TextBlock Grid.Column="1" Text="Basic" HorizontalAlignment="Left" Margin="129,2,0,13" Width="26" Grid.RowSpan="2" Grid.Row="1"/>
<TextBox Grid.Column="1" Width="81" HorizontalAlignment="Left" Text="{Binding Record.Basic,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Margin="162,2,0,3" Grid.Row="1"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="PF" HorizontalAlignment="Left" Margin="144,1,0,5" Width="12"/>
<TextBox Grid.Row="2" Grid.Column="1" Width="100" HorizontalAlignment="Left" Text="{Binding Record.PF,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Margin="162,2,0,1"/>
<TextBlock Grid.Column="1" Text="Salary" HorizontalAlignment="Left" Margin="268,-1,0,1" Width="36"/>
<TextBox Grid.Column="1" Width="100" HorizontalAlignment="Left" Text="{Binding Record.Salary,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" Margin="304,0,0,21" Grid.RowSpan="2"/>
<Button Content="Add" Command="{Binding SubmitCommand }" HorizontalAlignment="Left" Grid.Row="4" Margin="121,4,0,5" Width="44" Grid.Column="1"/>
<ListView x:Name="ListedView" ItemsSource="{Binding Records}" Width="Auto" Grid.Row="5" Margin="38,3,13,36" Grid.ColumnSpan="2">
<ListView.View >
<GridView >
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="Auto" />
<GridViewColumn Header="Company" DisplayMemberBinding="{Binding Company}" Width="Auto"/>
<GridViewColumn Header="Region" DisplayMemberBinding="{Binding Region}" Width="Auto" />
<GridViewColumn Header="HRA" DisplayMemberBinding="{Binding HRA}" Width="Auto" />
<GridViewColumn Header="Basic" DisplayMemberBinding="{Binding Basic}" Width="Auto" />
<GridViewColumn Header="PF" DisplayMemberBinding="{Binding PF}" Width="Auto" />
<GridViewColumn Header="Salary" DisplayMemberBinding="{Binding Salary}" Width="Auto" />
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Remove" Margin="1,36,50,150" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListView},Path=DataContext.SubmitCommand1}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
Any help is appreciated in this regard. Thanks
If I understand your issue correctly, you should bind the SelectedItem property of the ListView to be able to edit the currently selected item in the TextBox elements above the ListView:
<ListView SelectedItem="{Binding Record}" ... />
With or without Binding you can do it like this :
if ((sender as ListView).SelectedValue != null)
{
string item = (sender as ListView).SelectedValue.ToString();
SelectedIndex = (sender as ListView).SelectedIndex;
list.Items[SelectedIndex] = "Updated";
}
(I like to add a ContextMenu on my ListViewItems so it is easier for users to modify the specified clicked item) :
<ListView x:Name="list">
<ListView.ContextMenu>
<ContextMenu x:Name="contextmenu">
<MenuItem x:Name="Add" Header="Add" Click="Add_Click"/>
<MenuItem x:Name="Del" Header="Delete" Click="Del_Click"/>
<MenuItem x:Name="Update" Header="Update" Click="Update_Click"/>
</ContextMenu>
</ListView.ContextMenu>
</ListView>

Cannot locate xaml page in my WPF MVVM application

hi i have 3 folders in project namely Model,View, View Model. I moved my Xaml to View folder. My solution gets build properly buy when i run it shows the Error "cannot locate the source Userregistration.xaml".
Heres is my complete code
i have added themy folder structure for the reference. please help me i m not able to figure out this issue.
View
<Window x:Class="MVVMDemo.UserRegistrationView"
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:viewmodel="clr-namespace:MVVMDemo"
Title="Registration Window" Height="300" Width="575.851">
<Window.Resources>
<viewmodel:ViewModel x:Key="ViewModel"/>
<viewmodel:DatetimeToDateConverter x:Key="MyConverter"/>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource ViewModel}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Name" HorizontalAlignment="Center"/>
<TextBox Grid.Row="0" Grid.Column="1" Width="100" HorizontalAlignment="Center" Text="{Binding Student.Name, Mode=TwoWay}" Margin="76,0"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Age" HorizontalAlignment="Center"/>
<TextBox Grid.Row="1" Grid.Column="1" Width="100" HorizontalAlignment="Center" Text="{Binding Student.Age, Mode=TwoWay}"/>
<Button Content="Submit" Command="{Binding SubmitCommand}" HorizontalAlignment="Right" Grid.Row="2" Grid.Column="0"/>
<ComboBox Grid.Column="1" ItemsSource="{Binding FillCourseId}" Name="cmb_CourseIDName" HorizontalAlignment="Left" Margin="164.191,5,0,0"
Grid.Row="3" VerticalAlignment="Top" Width="168.342" Grid.RowSpan="2" DataContext="{Binding Source={StaticResource ViewModel}}" FontSize="8" IsReadOnly="True"
SelectedValue="{Binding Student.SCourseIDName,Mode=TwoWay}" RenderTransformOrigin="1.431,0.77">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding Path=CourseName, Mode=TwoWay}" FontSize="12"/>
<TextBlock Text=" - "/>
<TextBlock Text="{Binding Path=CourseID, Mode=TwoWay}" FontSize="12"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ListView ItemsSource="{Binding Students}" Grid.Row="4" Grid.Column="1" Margin="62.551,0,78.762,76.829"
ScrollViewer.CanContentScroll="False"
ScrollViewer.VerticalScrollBarVisibility="Visible" Height="85.152" VerticalAlignment="Bottom">
<ListView.View >
<GridView >
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="60"/>
<GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}" Width="60"/>
<GridViewColumn Header="Joining Date" DisplayMemberBinding="{Binding JoiningDate, Converter={StaticResource MyConverter}}" Width="80" />
<GridViewColumn Header="Course Name" DisplayMemberBinding="{Binding SCourseIDName.CourseName}" Width="80"/>
<GridViewColumn Header="CourseId" DisplayMemberBinding="{Binding SCourseIDName.CourseID}" Width="60"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MVVMDemo
{
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public string Course { get; set; }
public DateTime JoiningDate { get; set; }
public string CourseName { get; set; }
public string CourseID { get; set; }
public Student SCourseIDName { get; set; }
}
}
ViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Collections.ObjectModel;
using System.Data.SqlClient;
using System.Data;
using System.ComponentModel;
namespace MVVMDemo
{
public class ViewModel : ViewModelBase
{
static String connectionString = #"Data Source=RITESH-PC\SQLEXPRESS;Initial Catalog=SIT_Ritesh_DB;Integrated Security=True;";
SqlConnection con;
SqlCommand cmd;
private Student _student;
private ObservableCollection<Student> _students;
private ICommand _SubmitCommand;
public Student Student
{
get
{
return _student;
}
set
{
_student = value;
NotifyPropertyChanged("Student");
}
}
private ObservableCollection<Student> _fillCourseId = new ObservableCollection<Student>();
public ObservableCollection<Student> FillCourseId
{
get { return _fillCourseId; }
set
{
_fillCourseId = value;
OnPropertyChanged("SystemStatusData");
}
}
public ObservableCollection<Student> Students
{
get
{
return _students;
}
set
{
_students = value;
NotifyPropertyChanged("Students");
}
}
private Student _selectedcourseIdname;
public Student SelectedCourseIdName
{
get { return _selectedcourseIdname; }
set
{
_selectedcourseIdname = value;
OnPropertyChanged("SelectedCourseIdName");
}
}
public string SelectedCourseId
{
get { return _selectedcourseIdname.CourseID; }
set
{
_selectedcourseIdname.CourseID = value;
OnPropertyChanged("SelectedCourseId");
}
}
public string SelectedCourseName
{
get { return _selectedcourseIdname.CourseName; }
set
{
_selectedcourseIdname.CourseName = value;
OnPropertyChanged("SelectedCourseName");
}
}
public ICommand SubmitCommand
{
get
{
if (_SubmitCommand == null)
{
_SubmitCommand = new RelayCommand(param => this.Submit(),
null);
}
return _SubmitCommand;
}
}
//********************************************* Functions*******************************************//
public void GetCourseIdFromDB()
{
try
{
con = new SqlConnection(connectionString);
con.Open();
cmd = new SqlCommand("select * from dev_Course", con);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
adapter.Fill(dt);
// Student Student = new Student();
for (int i = 0; i < dt.Rows.Count; ++i)
FillCourseId.Add(new Student
{
CourseID = dt.Rows[i][0].ToString(),
CourseName = dt.Rows[i][2].ToString()
});
}
catch (Exception ex)
{
}
}
public ViewModel()
{
Student = new Student();
Students = new ObservableCollection<Student>();
Students.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Students_CollectionChanged);
GetCourseIdFromDB();
}
void Students_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
NotifyPropertyChanged("Students");
}
private void Submit()
{
Student.JoiningDate = DateTime.Today.Date;
//Students.Add(SelectedCourseIdName);
Students.Add(Student);
Student = new Student();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyname)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyname));
}
}
}
DateTimeConverter
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Windows.Data;
namespace MVVMDemo
{
public class DatetimeToDateConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
DateTime date = (DateTime)value;
return date.ToString("MM/d/yyyy");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace MVVMDemo
{
public class ViewModelBase:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged!=null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
you need to change it in the app.xmal in the line of the StartupUri
that he will be contact to the xmal in the View
example:
in the app.xmal file
<Application x:Class="UserRegistration.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:UserRegistration"
StartupUri="View/UserRegistrationView.xaml">
<Application.Resources>
</Application.Resources>
You need to edit app.xaml to point to the correct view file (including the folder name in the path) which in your case is the UserRegistrationView.Xaml. The app.xaml is responsible for starting your app not to view xaml code.
The folder name may not be required. I use Resharper which creates a namespace for each folder within a project in visual studio.

ListView into list

I have a wpf window with a ListView controller with bunch of item.
<ListView Name="lvUsers" SelectionChanged="lvUsers_SelectionChanged">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
<GridViewColumn Header="Mail" Width="150" DisplayMemberBinding="{Binding Mail}" />
</GridView>
</ListView.View>
</ListView>
Can I convert this ListView to a List<T> so that I can serialize it in XML file?
I tried this:
foreach (ListViewItem item in lvUsers.SelectedItems)
{
foreach (ListViewItem.ListViewSubItem subItem in lvUsers.SubItems)
{
}
}
But this code doesn't work cause ListViw doesn't containe SubItem property.
To serialize your data, your data got to be serializable. Where and how do you define it? The best way, would be to define an ObservableCollection<YourClass> and use it as ItemsSource in your ListView. Than, if YourClass is serializable, you can get data from that data collection, and serialize it.
<Window
x:Class="WpfApp2.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:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<Button Click="ButtonBase_OnClick">Serialize</Button>
<ListView ItemsSource="{Binding AllMyData}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
<GridViewColumn Header="Mail" Width="150" DisplayMemberBinding="{Binding Mail}" />
</GridView>
</ListView.View>
</ListView>
</StackPanel>
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows;
using System.Xml;
using System.Xml.Serialization;
namespace WpfApp2
{
public partial class MainWindow : Window
{
public class YourClass
{
public string Name { get; set; }
public string Age { get; set; }
public string Mail { get; set; }
}
public ObservableCollection<YourClass> AllMyData { get; set; }
public MainWindow()
{
InitializeComponent();
AllMyData = new ObservableCollection<YourClass>();
for (var i = 0; i < 3; i++)
{
AllMyData.Add(new YourClass { Name = i.ToString() });
}
this.DataContext = this;
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
XmlSerializer xsSubmit = new XmlSerializer(typeof(List<YourClass>));
var subReq = AllMyData.ToList();
var xml = "";
using (var sww = new StringWriter())
{
using (XmlWriter writer = XmlWriter.Create(sww))
{
xsSubmit.Serialize(writer, subReq);
xml = sww.ToString(); // Your XML
Debugger.Break();
}
}
}
}
}

Gridview Change event not firing and how to refresh the grid after inserting a record?

I an trying to get skills on WPF with MVVM pattern. i almost complete form with basic features but facing 2 problems
1) My Gridview Change Event not firing
2) How to refresh the grid after Inserting Record
My ViewModel and View code is given below
View Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
using DatabaseLayer;
using System.Data;
namespace WPFnMVVM.ViewModel
{
public class ContactsViewModel : WPFnMVVM.Common.VMBase
{
#region Variables
private int _Id;
private string _First_Name;
private string _Last_Name;
private DateTime _DOB;
private clstbl_Contacts _Contacts;
public WPFnMVVM.Common.RelayCommand _addCommand;
public DataTable _tblContacts;
#endregion
public ContactsViewModel()
{
_tblContacts = LoadContacts();
}
#region Public Properties
public int Id
{
get { return _Id; }
set { _Id = value; OnPropertyChanged("Id"); }
}
public string First_Name
{
get { return _First_Name; }
set { _First_Name = value; OnPropertyChanged("First_Name"); }
}
public string Last_Name
{
get { return _Last_Name; }
set { _Last_Name = value; OnPropertyChanged("Last_Name"); }
}
public DateTime DOB
{
get { return _DOB; }
set { _DOB = value; OnPropertyChanged("DOB"); }
}
public clstbl_Contacts Contacts
{
get { return _Contacts; }
set
{
_Contacts = value;
OnPropertyChanged("Contacts");
}
}
public DataTable ContactsList
{
get { return _tblContacts; }
set
{
_tblContacts = value;
OnPropertyChanged("ContactsList");
}
}
#endregion
#region Private Methods
private DataTable LoadContacts()
{
clstbl_Contacts objContact = new clstbl_Contacts(WPFnMVVM.Common.clsSettings.ConStr);
{
return objContact.Select();
};
}
private void AddContacts()
{
clstbl_Contacts objContacts = new clstbl_Contacts(WPFnMVVM.Common.clsSettings.ConStr);
objContacts.First_Name = First_Name;
objContacts.Last_Name = Last_Name;
objContacts.DOB = DOB;
objContacts.Insert();
}
#endregion
#region Commands
public ICommand AddCommand
{
get
{
if (_addCommand == null)
{
_addCommand = new WPFnMVVM.Common.RelayCommand(
param => this.AddContacts(),
param => true
);
}
return _addCommand;
}
}
#endregion
}
}
View
<Window x:Class="WPFnMVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:VM="clr-namespace:WPFnMVVM.ViewModel"
xmlns:View="clr-namespace:WPFnMVVM"
Title="MainWindow" Height="350" Width="337">
<Window.DataContext>
<VM:ContactsViewModel/>
</Window.DataContext>
<Grid Name="MyGrid">
<TextBox HorizontalAlignment="Left" Height="23" Margin="95,13,0,0" TextWrapping="Wrap" Text="{Binding Path=First_Name, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120" />
<TextBox HorizontalAlignment="Left" Height="23" Margin="95,47,0,0" TextWrapping="Wrap" Text="{Binding Path=Last_Name, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/>
<Label Content="First Name" HorizontalAlignment="Left" Margin="8,10,0,0" VerticalAlignment="Top"/>
<Label Content="Last Name" HorizontalAlignment="Left" Margin="9,47,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.68,1.974"/>
<Label Content="DOB" HorizontalAlignment="Left" Margin="8,75,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.68,1.974"/>
<DatePicker Height="25" HorizontalAlignment="Left" Margin="95,76,0,0" Name="datePicker1"
VerticalAlignment="Top" Width="120" SelectedDate="{Binding Path=DOB, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Add" HorizontalAlignment="Left" Margin="9,118,0,0" VerticalAlignment="Top" Width="75" Command="{Binding Path=AddCommand}"/>
<Button Content="Update" HorizontalAlignment="Left" Margin="102,118,0,0" VerticalAlignment="Top" Width="75"/>
<Button Content="Delete" HorizontalAlignment="Left" Margin="193,118,0,0" VerticalAlignment="Top" Width="75"/>
<ListView BorderBrush="White" ItemsSource="{Binding Path=ContactsList, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch" Margin="11,156,10,10" SelectedValue="{Binding Path=Contacts, UpdateSourceTrigger=PropertyChanged}">
<ListView.View>
<GridView>
<GridViewColumn Header="First Name"
DisplayMemberBinding="{Binding Path=First_Name}" Width="70" />
<GridViewColumn Header="Last Name"
DisplayMemberBinding="{Binding Path=Last_Name}" Width="70" />
<GridViewColumn Header="DOB"
DisplayMemberBinding="{Binding Path=DOB}" Width="70" />
</GridView>
</ListView.View>
</ListView >
</Grid>
</Window>
Please guide and also give me ref of any practical application with sql crud functions if possible from which i can enhance my skills.
Thanks
DataTable does not implement INotifyPropertyChanged, so you will have issues binding directly to it. You'll see the initial data but then changes to the data will not be reflected in the view.
I'd say the easiest alternative is to use a DataView, which does implement INotifyPropertyChanged. You can easily get a view for your table by using _tblContacts.DefaultView.
#Rob H , I change my logic a bit a good think is now i am getting my values and record also inserting but now the only problem is gridview is not refreshing after insertionof record.
please view a code below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
using DatabaseLayer;
using System.Data;
namespace WPFnMVVM.ViewModel
{
public class ContactsViewModel : WPFnMVVM.Common.VMBase
{
#region Variables
private int _Id;
private string _First_Name;
private string _Last_Name;
private DateTime _DOB;
private clstbl_Contacts _Contacts;
public WPFnMVVM.Common.RelayCommand _addCommand;
public ObservableCollection<clstbl_Contacts> _ContactsList;
#endregion
#region Contructor
public ContactsViewModel()
{
LoadContacts();
}
#endregion
#region Public Properties
public int Id
{
get { return _Id; }
set { _Id = value; OnPropertyChanged("Id"); }
}
public string First_Name
{
get { return _First_Name; }
set { _First_Name = value;
OnPropertyChanged("First_Name"); }
}
public string Last_Name
{
get { return _Last_Name; }
set { _Last_Name = value; OnPropertyChanged("Last_Name"); }
}
public DateTime DOB
{
get { return _DOB; }
set { _DOB = value; OnPropertyChanged("DOB"); }
}
public clstbl_Contacts Contacts
{
get { return _Contacts; }
set
{
_Contacts = value;
OnPropertyChanged("Contacts");
GetValuesFromModel();
}
}
public ObservableCollection<clstbl_Contacts> ContactsList
{
get { return _ContactsList; }
set
{
_ContactsList = value;
OnPropertyChanged("ContactsList");
}
}
#endregion
#region Methods
private void LoadContacts()
{
clstbl_Contacts objContact = new clstbl_Contacts(WPFnMVVM.Common.clsSettings.ConStr);
DataTable dt = objContact.Select();
_ContactsList = new ObservableCollection<clstbl_Contacts>();
for (int i = 0; i < dt.Rows.Count; i++)
{
_ContactsList.Add(new clstbl_Contacts { Id = Convert.ToInt16(dt.Rows[i]["ID"].ToString())
,First_Name = dt.Rows[i]["First_Name"].ToString(),
Last_Name = dt.Rows[i]["Last_Name"].ToString(),
DOB = Convert.ToDateTime(dt.Rows[i]["DOB"].ToString())
});
}
}
private void AddContacts()
{
clstbl_Contacts objContacts = new clstbl_Contacts(WPFnMVVM.Common.clsSettings.ConStr);
objContacts.First_Name = First_Name;
objContacts.Last_Name = Last_Name;
objContacts.DOB = DOB;
objContacts.Insert();
}
private void GetValuesFromModel()
{
Id = _Contacts.Id;
First_Name = _Contacts.First_Name;
Last_Name = _Contacts.Last_Name;
DOB = _Contacts.DOB;
}
#endregion
#region Commands
public ICommand AddCommand
{
get
{
if (_addCommand == null)
{
_addCommand = new WPFnMVVM.Common.RelayCommand(
param => this.AddContacts(),
param => true
);
}
return _addCommand;
}
}
#endregion
}
}
View
<Window x:Class="WPFnMVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:VM="clr-namespace:WPFnMVVM.ViewModel"
xmlns:View="clr-namespace:WPFnMVVM"
Title="MainWindow" Height="350" Width="337">
<Window.DataContext>
<VM:ContactsViewModel/>
</Window.DataContext>
<Grid Name="MyGrid">
<TextBox HorizontalAlignment="Left" Height="23" Margin="95,13,0,0" TextWrapping="Wrap"
Text="{Binding Path=First_Name, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120" />
<TextBox HorizontalAlignment="Left" Height="23" Margin="95,47,0,0" TextWrapping="Wrap" Text="{Binding Path=Last_Name, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/>
<Label Content="First Name" HorizontalAlignment="Left" Margin="8,10,0,0" VerticalAlignment="Top"/>
<Label Content="Last Name" HorizontalAlignment="Left" Margin="9,47,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.68,1.974"/>
<Label Content="DOB" HorizontalAlignment="Left" Margin="8,75,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.68,1.974"/>
<DatePicker Height="25" HorizontalAlignment="Left" Margin="95,76,0,0" Name="datePicker1"
VerticalAlignment="Top" Width="120" SelectedDate="{Binding Path=DOB, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Add" HorizontalAlignment="Left" Margin="9,118,0,0" VerticalAlignment="Top" Width="75" Command="{Binding Path=AddCommand}"/>
<Button Content="Update" HorizontalAlignment="Left" Margin="102,118,0,0" VerticalAlignment="Top" Width="75"/>
<Button Content="Delete" HorizontalAlignment="Left" Margin="193,118,0,0" VerticalAlignment="Top" Width="75"/>
<ListView BorderBrush="White" ItemsSource="{Binding Path=ContactsList, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch" Margin="11,156,10,10" SelectedValue="{Binding Path=Contacts, UpdateSourceTrigger=PropertyChanged}">
<ListView.View>
<GridView>
<GridViewColumn Header="First Name"
DisplayMemberBinding="{Binding Path=First_Name}" Width="70" />
<GridViewColumn Header="Last Name"
DisplayMemberBinding="{Binding Path=Last_Name}" Width="70" />
<GridViewColumn Header="DOB"
DisplayMemberBinding="{Binding Path=DOB}" Width="70" />
</GridView>
</ListView.View>
</ListView >
</Grid>
</Window>

Categories