Cannot locate xaml page in my WPF MVVM application - c#

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.

Related

How to perform a correct binding using wpf MVVM

I'm working on a bank application in c# wpf using the MVVM pattern which allows a manager in charge of a branch to display the data of one of the customers of this branch in another tab by selecting the line corresponding to this customer. I use a custom framework.
Here is my Xaml code corresponding to the main view that displays the agencies for which the Manager is responsible:
<f:UserControlBase x:Class="BankingApp.View.ManagerAgencyView"
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:vm="clr-namespace:BankingApp.ViewModel"
xmlns:vw="clr-namespace:BankingApp.View"
xmlns:f="clr-namespace:PRBD_Framework;assembly=PRBD_Framework"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=vm:ManagerAgencyViewModel,
IsDesignTimeCreatable=False}"
FontSize="14" d:DesignHeight="498" d:DesignWidth="918">
<UserControl.DataContext>
<vm:ManagerAgencyViewModel x:Name="vm"/>
</UserControl.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock Margin="5" Text="Agency:"/>
<ComboBox
Margin="5,5,5,5"
Grid.Column="1"
ItemsSource="{Binding Path=Agencies,Mode=TwoWay}"
DisplayMemberPath="Name"
SelectedItem="{Binding SelectedAgency}"
/>
<f:MyDataGrid
Grid.Row="1"
ItemsSource="{Binding Clients}"
SelectedItem="{Binding SelectedClient}"
CanUserAddRows="False"
AutoGenerateColumns="False"
x:Name="gridAccesses" Grid.ColumnSpan="2" Margin="0,0,5,0"
>
<DataGrid.Columns>
<DataGridTextColumn Header="idClient" Width="auto" Binding="{Binding UserId}"
IsReadOnly="True" />
<DataGridTextColumn Header="FirstName" Width="*" Binding="{Binding FirstName}"
IsReadOnly="True" />
<DataGridTextColumn Header="LastName" Width="*" Binding="{Binding LastName}"
IsReadOnly="True" />
</DataGrid.Columns>
</f:MyDataGrid>
<Button Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" Width="80" Margin="10"
Content="New Client" Command=""/>
<f:MyTabControl Grid.Row="3" Grid.ColumnSpan="2" >
<TabItem Header="Client">
<vw:ManagerClientDataView x:Name="ClientData" DataContext="{Binding
ManagerClientData, ElementName=vm}"/>
</TabItem>
<TabItem Header="Account">
<vw:ManagerClientAccount/>
</TabItem>
</f:MyTabControl>
</Grid>
</f:UserControlBase>
When I select on one of the agencies, it shows me all the clients of this agency like this:
enter image description here
here is the corresponding viewModel
using BankingApp.Model;
using PRBD_Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankingApp.ViewModel {
public class ManagerAgencyViewModel : ViewModelCommon {
public ManagerClientDataViewModel ManagerClientData { get; private set; } = new
ManagerClientDataViewModel();
public ManagerAgencyViewModel() {
OnRefreshData();
}
public ObservableCollectionFast<Agency> Agencies { get; set; } = new();
public ObservableCollectionFast<Client> Clients { get; set; } = new();
private Client _selectedClient;
public Client SelectedClient {
get => _selectedClient;
set {
SetProperty(ref _selectedClient, value, () => ManagerClientData.SelectedClient =
value);
}
}
private Agency _selectedAgency;
public Agency SelectedAgency {
get => _selectedAgency;
set => SetProperty(ref _selectedAgency, value, () => ClientOfAgency(SelectedAgency));
}
private void ClientOfAgency(Agency agency) {
if (agency != null)
Clients.RefreshFromModel(Context.Clients.Where(c => c.Agency.AgencyId ==
agency.AgencyId));
}
protected override void OnRefreshData() {
Agencies.RefreshFromModel(Context.Agencies.OrderBy(a => a.Name));
ClientOfAgency(SelectedAgency);
}
public void init() {
}
}
}
Here is the code of my tab to display the data of the selected client:
<f:UserControlBase x:Class="BankingApp.View.ManagerClientDataView"
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:vm="clr-namespace:BankingApp.ViewModel"
xmlns:vw="clr-namespace:BankingApp.View"
xmlns:f="clr-namespace:PRBD_Framework;assembly=PRBD_Framework"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Margin="0,10,0,10">
<TextBlock Text="FirstName:"/>
<TextBox Text="{Binding Firstname}"/>
</StackPanel>
<StackPanel Grid.Row="1" Margin="0,0,0,10">
<TextBlock Text="LastName:"/>
<TextBox Text="{Binding Lastname}"/>
</StackPanel>
<StackPanel Grid.Row="2" Margin="0,0,0,10">
<TextBlock Text="Email:"/>
<TextBox Text="{Binding Email}"/>
</StackPanel>
<StackPanel Grid.Row="3" Margin="0,0,0,10">
<TextBlock Text="Password:"/>
<PasswordBox f:PasswordHelper.Password="{Binding Password, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
<StackPanel Grid.Row="4">
<TextBlock Text="Confirm Password:"/>
<PasswordBox f:PasswordHelper.Password="{Binding Password, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</Grid>
</f:UserControlBase>
And the corresponding viewmodel
using BankingApp.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PRBD_Framework;
namespace BankingApp.ViewModel {
public class ManagerClientDataViewModel : ViewModelCommon {
private Client _selectedClient;
public Client SelectedClient {
get => _selectedClient;
set {
SetProperty(ref _selectedClient, value);
Console.WriteLine(SelectedClient.FirstName);
}
}
public string Firstname {
get => SelectedClient?.FirstName;
set => SetProperty(SelectedClient.FirstName, value, SelectedClient, (s, v) => {
s.FirstName = v;
Console.WriteLine(s.FirstName);
});
}
public string Lastname {
get => SelectedClient?.LastName;
set => SetProperty(SelectedClient.LastName, value, SelectedClient, (s, v) => {
s.LastName = v;
Console.WriteLine(s.LastName);
});
}
public string Email {
get => SelectedClient?.Email;
set => SetProperty(SelectedClient.Email, value, SelectedClient, (s, v) => {
s.Email = v;
Console.WriteLine(s.Email);
});
}
public string Password {
get => SelectedClient?.Password;
set => SetProperty(SelectedClient.Password, value, SelectedClient, (s, v) => {
s.Password = v;
});
}
}
}
My problem is that when I select a customer, his data does not appear in the form, could someone help me? Thanks
this is a working example without the use of any frameworks. Maybe this helps to track down your issue or just use this code ;-)
XAML:
<Window x:Class="WpfApp1AgencyTest.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:WpfApp1AgencyTest"
mc:Ignorable="d"
xmlns:vm="clr-namespace:WpfApp1AgencyTest"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<vm:ManagerAgencyViewModel/>
</Window.DataContext>
<Grid>
<TabControl>
<TabItem Header="Manager" >
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<TextBlock Margin="5" Text="Agency:"></TextBlock>
<ComboBox Grid.Column="1" Margin="5,5,5,5"
ItemsSource="{Binding Path=Agencies}"
DisplayMemberPath="Name"
SelectedItem="{Binding SelectedAgency}"
></ComboBox>
</Grid>
<DataGrid
Grid.Row="1"
ItemsSource="{Binding SelectedAgency.Clients}"
SelectedItem="{Binding SelectedClient}"
AutoGenerateColumns="False"
>
<DataGrid.Columns>
<DataGridTextColumn Header="id" Binding="{Binding ID}"></DataGridTextColumn>
<DataGridTextColumn Header="First name" Binding="{Binding Firstname}"></DataGridTextColumn>
<DataGridTextColumn Header="Last name" Binding="{Binding Lastname}"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
<TabControl>
<TabItem Header="Client">
<StackPanel DataContext="{Binding SelectedClient}">
<TextBlock>First name:</TextBlock>
<TextBox Text="{Binding Firstname}"></TextBox>
<TextBlock>Last name:</TextBlock>
<TextBox Text="{Binding Lastname}"></TextBox>
<TextBlock>Password:</TextBlock>
<TextBox Text="{Binding Password}"></TextBox>
<TextBlock>Confirm Password:</TextBlock>
<TextBox></TextBox>
</StackPanel>
</TabItem>
<TabItem Header="Account">
</TabItem>
</TabControl>
</StackPanel>
</TabItem>
</TabControl>
</Grid>
</Window>
class Client
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WpfApp1AgencyTest
{
public class Client : INotifyPropertyChanged
{
private string id;
public string ID
{
get { return id; }
set { id = value; RaisePropertyChange(); }
}
private string firstname;
public string Firstname
{
get => firstname; set
{
firstname = value;
RaisePropertyChange();
}
}
private string lastname;
public string Lastname
{
get => lastname; set
{
lastname = value;
RaisePropertyChange();
}
}
private string password;
public string Password
{
get => password; set
{
password = value;
RaisePropertyChange();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChange([CallerMemberName] string caller = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(caller));
}
}
}
}
class Agency
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WpfApp1AgencyTest
{
public class Agency
{
private string name;
public string Name
{
get { return name; }
set { name = value; RaisePropertyChange(); }
}
public ObservableCollection<Client> Clients { get; set; } = new();
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChange([CallerMemberName] string caller = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(caller));
}
}
}
}
class ManagerAgencyViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WpfApp1AgencyTest
{
public class ManagerAgencyViewModel
{
public ManagerAgencyViewModel()
{
Agencies =
new ObservableCollection<Agency>() {
new Agency()
{
Name="Dexia",
Clients = new ObservableCollection<Client>()
{
new Client(){ID="1", Firstname = "b",Lastname="inconnu"},
new Client(){ ID="2",Firstname = "Mustafa",Lastname="Azoud" },
new Client{ID="3",Firstname="Samiha",Lastname="Draa"}
}
},
new Agency()
{
Name="2Advacend",
Clients = new ObservableCollection<Client>()
{
new Client(){ ID="4", Firstname = "Joe",Lastname="Doe"},
new Client(){ ID="5", Firstname = "Max",Lastname="Headroom" },
}
}
};
}
public ObservableCollection<Agency> Agencies { get; set; }
private Agency selectedAgency;
public Agency SelectedAgency
{
get => selectedAgency;
set
{
selectedAgency = value;
RaisePropertyChange();
}
}
private Client selectedClient;
public Client SelectedClient { get => selectedClient; set {
selectedClient = value;
RaisePropertyChange();
} }
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChange([CallerMemberName] string caller = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(caller));
}
}
}
}

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>

WPF Treeview - Define Parent and Children Nodes?

I'm trying to implement a TreeView in WPF to show children that display the charge activity, adjustment activity, etc on a daily account balance. I was going to start by first rendering the daily account balance details as the parent node (which I've done successfully), and then try, for instance, showing a text segment as the child for testing and then expanding from there to show children that I would preferably render as tables to show what was charged that day, and then separately what was adjusted on a charge that day, etc. This is where I'm stuck.
Here's my XAML code:
<Window x:Class="Client_Invoice_Auditor.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:Client_Invoice_Auditor"
xmlns:self="clr-namespace:Client_Invoice_Auditor.CoreClientAR"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20*"/>
<RowDefinition Height="80*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Grid.Column="0">
<StackPanel Orientation="Vertical">
<DockPanel VerticalAlignment="Top" Height="20" Panel.ZIndex="1">
<Menu Name="fileMenu" Width="Auto" DockPanel.Dock="Top">
<MenuItem Header="File">
<MenuItem Header="Open Account File" Click="menuOpenFile_Click"/>
<MenuItem Header="Exit" Click="menuExit_Click"/>
</MenuItem>
<MenuItem Header="Options">
<!--<MenuItem Header="Update" Click="update_Click"/>-->
<MenuItem Header="About" Click="about_Click"/>
</MenuItem>
</Menu>
</DockPanel>
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Center" Height="Auto">
<StackPanel Width="Auto" Orientation="Horizontal" HorizontalAlignment="Center">
<Border BorderBrush="MediumAquamarine" BorderThickness="2">
<Label Name="AccountNumber"/>
</Border>
<Border BorderBrush="MediumAquamarine" BorderThickness="2">
<Label Name="AcctDesc"/>
</Border>
<Border BorderBrush="MediumAquamarine" BorderThickness="2">
<Label Name="Organization"/>
</Border>
</StackPanel>
</WrapPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<Label Margin="20,10,0,0" Content="Activity Date Time" />
<Label Margin="60,10,0,0" Content="Beginning Balance" />
<Label Margin="10,10,0,0" Content="Charge Amount" />
<Label Margin="30,10,0,0" Content="Adjustments" />
<Label Margin="40,10,0,0" Content="Payments" />
<Label Margin="60,10,0,0" Content="End Balance" />
</StackPanel>
</StackPanel>
</Grid>
<Grid Grid.Row="1" Grid.Column="0">
<TreeView Name="DABView">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type self:dailyAccountBalance}">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Width="150" Text="{Binding DabActivityDate}" />
<TextBlock Width="100" Margin="20,0,0,0" Text="{Binding BegBalance}" />
<TextBlock Width="100" Margin="20,0,0,0" Text="{Binding ChrgAmount}" />
<TextBlock Width="100" Margin="20,0,0,0" Text="{Binding AdjAmount}" />
<TextBlock Width="100" Margin="20,0,0,0" Text="{Binding PmtAmount}" />
<TextBlock Width="100" Margin="20,0,0,0" Text="{Binding EndBalance}" />
</StackPanel>
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate x:Key="TestChild">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Text="YOU IZ GOOD" />
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</Grid>
</Window>
My Main Window's codebehind:
using Client_Invoice_Auditor.CoreClientAR;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 Client_Invoice_Auditor
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public string accountFile;
public MainWindow()
{
InitializeComponent();
OpenAccountFile();
}
private void OpenAccountFile()
{
accountFile = "";
//errorFilters.Clear();
// Displays an OpenFileDialog so the user can select a file.
Microsoft.Win32.OpenFileDialog openFileDialog1 = new Microsoft.Win32.OpenFileDialog();
openFileDialog1.Filter = "Account Files|*.acct";
openFileDialog1.Title = "Select an account file";
if (openFileDialog1.ShowDialog() == true)
{
// Assign the cursor in the Stream to the Form's Cursor property.
accountFile = openFileDialog1.FileName;
//openFileDialog1.Dispose();
}
if (accountFile == "")
{
/*System.Windows.MessageBox.Show("File must be selected in order to continue - exiting now."
, "No File Selected", MessageBoxButton.OK);
this.Close();*/
if (!AcctDesc.HasContent)
{
AcctDesc.Content = "No account file Loaded";
//Version version = Assembly.GetExecutingAssembly().GetName().Version;
}
}
else
{
//openFileDialog1 = null;
Console.WriteLine("Account file path is: " + accountFile);
DataTable dataAR = new DataTable();
try
{
Tuple<accountARHeader, List<dailyAccountBalance>, DataTable> loadedAR = dabARLoader.LoadARData(accountFile);
//dataAR = loadedAR.Item2;
AccountNumber.Content = "Account Number: " + loadedAR.Item1.AccountNumber;
AcctDesc.Content = "Description: " + loadedAR.Item1.AccountDescription;
Organization.Content = "Client Organization: " + loadedAR.Item1.OrganizationName;
//TreeViewItem dummy = new TreeViewItem();
//dummy.DataContext = "Hi";
//loadedAR.Item2.First().Dummy.Add("La");
//DABView.Items.Add(dummy);
DABView.ItemsSource = loadedAR.Item2;
//DABView.DisplayMemberPath = "A";
}
catch (Exception e)
{
System.Windows.MessageBox.Show("I don't wanna open this file! Try another. Error: " + e.Message);
OpenAccountFile();
}
}
}
private void menuOpenFile_Click(object sender, RoutedEventArgs e)
{
OpenAccountFile();
}
private void menuExit_Click(object sender, RoutedEventArgs e)
{
Close();
}
private void about_Click(object sender, RoutedEventArgs e)
{
System.Windows.MessageBox.Show("I heard you like clicking buttons.");
}
}
}
And finally, my relevant class file:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace Client_Invoice_Auditor.CoreClientAR
{
public class dailyAccountBalance
{
double dabID;
DateTime dabActivityDate;
double begBalance;
double endBalance;
double chrgAmount;
double adjAmount;
double pmtAmount;
string dabActivitySegment;
public double DabID { get => dabID; set => dabID = value; }
public double BegBalance { get => begBalance; set => begBalance = value; }
public double EndBalance { get => endBalance; set => endBalance = value; }
public string DabActivitySegment { get => dabActivitySegment; set => dabActivitySegment = value; }
public DateTime DabActivityDate { get => dabActivityDate; set => dabActivityDate = value; }
public double ChrgAmount { get => chrgAmount; set => chrgAmount = value; }
public double AdjAmount { get => adjAmount; set => adjAmount = value; }
public double PmtAmount { get => pmtAmount; set => pmtAmount = value; }
public ObservableCollection<dailyAccountBalance> Items { get; set; }
public List<string> Dummy { get => dummy; set => dummy = value; }
public IList<TreeViewItem> DummyItems { get => dummyItems; set => dummyItems = value; }
public dailyAccountBalance()
{
this.Items = new ObservableCollection<dailyAccountBalance>();
}
List<string> dummy = new List<string>();
IList<TreeViewItem> dummyItems;
}
}
Is there a way, for instance, that I can show a dummy string as ONE child in the TreeView when it expands? Do I need to implement expand methods for this?
Thanks so much in advance.
Typically what I've done in the past is add a DummyNode to the TreeNode, bind the "IsExpanded" TreeViewItem property in the TreeViewItem style to a IsExpanded property on my Node class in my View Model, and add a bool _isLoaded flag. Then when the IsExpanded it triggered I check if _isLoaded is true, and if not I then go and load all of the subsequent data and set the _isLoaded to true.
btw... I use Prism to give me my BindableBase class that implements the INotifyPropertyChanged event for OnPropertyChanged. You can choose to implement that yourself instead of using BindableBase.
Example:
Node Class
public class TreeData : BindableBase
{
private bool _isExpanded = false;
private bool _isSelected = false;
private bool _hasChildren = false;
private Func<List<TreeData>> _getChildrenMethod;
private bool _isLoaded = false;
public TreeData(string value, bool hasChildren, Func<List<TreeData>> getChildren)
{
Value = value;
_hasChildren = hasChildren;
_getChildrenMethod = getChildren;
if(hasChildren)
{
Children.Add(new TreeNode("Dummy", false, null));
}
}
public ObservableCollection<TreeData> Children { get; set; } = new ObservableCollection<TreeData>();
public string Value {get;set;}
public bool IsSelected
{
get { return _isSelected; }
set { _isSelected = value; OnPropertyChanged(); }
}
public bool IsExpanded
{
get { return _isExpanded; }
set
{
_isExpanded = value;
if(!_isLoaded)
{
// Call load method here
if(_addChildrenMethod != null && _hasChildren)
{
Children.Clear();
Children.AddMany(_addChildrenMethod());
}
_isLoaded = true;
}
OnPropertyChanged();
}
}
}
View Model Class (owns the list of items)
public class BusinessViewModel
{
public ObservableCollection<TreeData> Items { get; set; } = new ObservableCollection<TreeData>();
public BusinessViewModel()
{
Items.Add(new TreeData("Root Item", hasChildren: true, GetChildren));
}
public List<TreeData> GetChildren()
{
return new List<TreeData>()
{
new TreeData("Child", hasChildren: false, null);
};
}
}
Then the XAML
<TreeView ItemSource="{Binding Items}" >
<TreeView.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Blue" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.Resources>
</TreeView>
Hope that helps :D

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>

Binding items into ListBox multiple columns

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;
}
}

Categories