Answered by:
populate wpf textbox from listbox selected item - MVVM

Question
-
Hello,
I am working on WPF MVVM...
The window has a listbox which is populated with FullNames of students
The bit I need help on is when you click on a name in the listbox then the textboxes to be populated with FirstName in textbox1 and textbox2 with Address1 fieldsThis is what I am doing so far but DetailData does not seem to be populating...
//frmDetailsTest <Window x:Class="Rustam.frmDetailsTest" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="frmDetailsTest" Height="501.6" Width="455.686" xmlns:scr="clr-namespace:Rustam" Loaded="Window_Loaded"> <Window.Resources> <scr:clsStudentViewModel x:Key="StudentViewModel"/> </Window.Resources> <Grid Margin="0,0,5.2,-0.2" DataContext="{Binding Source={StaticResource StudentViewModel}}"> <StackPanel Orientation="Vertical"> <ListBox Name="lstNames" ItemsSource="{Binding Path=DataCollection}" SelectedValuePath="StudentID" DisplayMemberPath="FullName" HorizontalAlignment="Left" Height="253" Margin="10,10,0,0" VerticalAlignment="Top" Width="236" SelectionChanged="lstNames_SelectionChanged" Grid.ColumnSpan="7" > </ListBox> <Grid Grid.Row="2" Margin="5,5,4.6,5" x:Name="grdDetail" Height="166" DataContext="{Binding Path=DetailData}" > <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="120"></ColumnDefinition> <ColumnDefinition Width="*"></ColumnDefinition> </Grid.ColumnDefinitions> <TextBox Text="{Binding Path=Address1, Mode=TwoWay}" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="10,9.2,0,-30.6" Grid.Row="1" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> <TextBox Text="{Binding Path=FirstName, Mode=TwoWay}" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="10,37.2,0,-57" Grid.Row="1" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> </Grid> </StackPanel> </Grid> </Window>
using System.Data; using System.Data.SqlClient; using System.ComponentModel; using System.Collections.ObjectModel; using DataAccess; namespace Rustam { public class clsStudentViewModel : INotifyPropertyChanged { clsStudentAccess _DataManager = new clsStudentAccess(); #region Constructor - Initialize Product Data Collection public clsStudentViewModel() { DataCollection = _DataManager.GetStudentNamesCol(); } #endregion #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChanged(string propertyName) { PropertyChangedEventHandler handler = this.PropertyChanged; if (handler != null) { PropertyChangedEventArgs args = new PropertyChangedEventArgs(propertyName); // Raise the PropertyChanged event. handler(this, args); } } #endregion #region DataCollection Property private ObservableCollection<clsStudentDetails> _DataCollection; public ObservableCollection<clsStudentDetails> DataCollection { get { return _DataCollection; } set { _DataCollection = value; RaisePropertyChanged("DataCollection"); } } #endregion #region DetailData Property private clsStudentDetails mDetailData; public clsStudentDetails DetailData { get { return mDetailData; } set { mDetailData = value; RaisePropertyChanged("DetailData"); } } #endregion } ----------------------------------------------------------------------- ----------------------------------------------------------------------- -------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Data.Common; using System.ComponentModel; using System.Collections.ObjectModel; namespace DataAccess { public class clsStudentAccess { public ObservableCollection<clsStudentDetails> GetStudentNamesCol() { ObservableCollection<clsStudentDetails> ret = new ObservableCollection<clsStudentDetails>(); // get a configured DbCommand object DbCommand comm = clsGenericDataAccess.CreateCommand(); // set the stored procedure name comm.CommandText = "uspGetAllStudentNames"; // execute the stored procedure and return the results DataTable table = new DataTable(); table = clsGenericDataAccess.ExecuteSelectCommand(comm); if (table.Rows.Count > 0) { foreach (DataRow dr in table.Rows) { clsStudentDetails student = new clsStudentDetails(); student.StudentID = int.Parse(dr["StudentID"].ToString()); student.FullName = dr["FullName"].ToString(); ret.Add(student); } } return ret; } public clsStudentDetails GetStudentDetailsUniqueMVVM(int intStudentID) { DbCommand comm = clsGenericDataAccess.CreateCommand(); comm.CommandText = "uspGetStudentDetailsUnique"; DbParameter param = comm.CreateParameter(); if (intStudentID > 0) { param.ParameterName = "@StudentID"; param.Value = intStudentID; param.DbType = DbType.Int32; comm.Parameters.Add(param); } DataTable table = new DataTable(); table = clsGenericDataAccess.ExecuteSelectCommand(comm); clsStudentDetails details = new clsStudentDetails(); if (table.Rows.Count > 0) { details.FirstName = table.Rows[0]["FirstName"].ToString(); details.Address1 = table.Rows[0]["Address1"].ToString(); } return details; } -------------------------------------------------------------------- -------------------------------------------------------------------- -------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; namespace DataAccess { public class clsStudentDetails : INotifyPropertyChanged { #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } #endregion private int _StudentID; public int StudentID { get { return _StudentID; } set { if (_StudentID != value) { _StudentID = value; RaisePropertyChanged("StudentID"); } } } private string _FullName; public string FullName { get { return _FullName; } set { if (_FullName != value) { _FullName = value; RaisePropertyChanged("FullName"); } } } private string _FirstName; public string FirstName { get { return _FirstName; } set { if (_FirstName != value) { _FullName = value; RaisePropertyChanged("FirstName"); } } } private string _Address1; public string Address1 { get { return _Address1; } set { if (_Address1 != value) { _Address1 = value; RaisePropertyChanged("Address1"); } } } } }
Wednesday, September 2, 2015 4:15 PM
Answers
-
Hi arkiboys,
you need to set the DetailData-property of your ViewModel when an item in the ListBox is selected. To do this, bind the SelectedItem-Property of the ListBox to the DetailData-property of your ViewModel:
<ListBox Name="lstNames" ItemsSource="{Binding Path=DataCollection}" SelectedItem="{Binding Path=DetailData,Mode=TwoWay}"
Now you see the Address shows up correctly, but not so the FirstName. The FirstName does not show up because you've a typo in the property. When you look at your code, you see that you set the _FullName-field inside of the setter instead of the _FirstName-field. So change this like here:
public string FirstName { get { return _FirstName; } set { if (_FirstName != value) { _FirstName = value; // _FullName = value; RaisePropertyChanged("FirstName"); } } }
Now it works like a charm. ;-)
Thomas Claudius Huber
"If you can't make your app run faster, make it at least look & feel extremly fast"
My latest Pluralsight-courses:
XAML Layout in Depth
Windows Store Apps - Data Binding in Depth
twitter: @thomasclaudiush
homepage: www.thomasclaudiushuber.com- Proposed as answer by Andy ONeill Thursday, September 3, 2015 8:54 AM
- Marked as answer by Xavier Xie-MSFT Wednesday, September 16, 2015 9:21 AM
Wednesday, September 2, 2015 5:32 PM
All replies
-
Hi arkiboys,
you need to set the DetailData-property of your ViewModel when an item in the ListBox is selected. To do this, bind the SelectedItem-Property of the ListBox to the DetailData-property of your ViewModel:
<ListBox Name="lstNames" ItemsSource="{Binding Path=DataCollection}" SelectedItem="{Binding Path=DetailData,Mode=TwoWay}"
Now you see the Address shows up correctly, but not so the FirstName. The FirstName does not show up because you've a typo in the property. When you look at your code, you see that you set the _FullName-field inside of the setter instead of the _FirstName-field. So change this like here:
public string FirstName { get { return _FirstName; } set { if (_FirstName != value) { _FirstName = value; // _FullName = value; RaisePropertyChanged("FirstName"); } } }
Now it works like a charm. ;-)
Thomas Claudius Huber
"If you can't make your app run faster, make it at least look & feel extremly fast"
My latest Pluralsight-courses:
XAML Layout in Depth
Windows Store Apps - Data Binding in Depth
twitter: @thomasclaudiush
homepage: www.thomasclaudiushuber.com- Proposed as answer by Andy ONeill Thursday, September 3, 2015 8:54 AM
- Marked as answer by Xavier Xie-MSFT Wednesday, September 16, 2015 9:21 AM
Wednesday, September 2, 2015 5:32 PM -
Hi arkiboys,
you need to set the DetailData-property of your ViewModel when an item in the ListBox is selected. To do this, bind the SelectedItem-Property of the ListBox to the DetailData-property of your ViewModel:
<ListBox Name="lstNames" ItemsSource="{Binding Path=DataCollection}" SelectedItem="{Binding Path=DetailData,Mode=TwoWay}"
Now you see the Address shows up correctly, but not so the FirstName. The FirstName does not show up because you've a typo in the property. When you look at your code, you see that you set the _FullName-field inside of the setter instead of the _FirstName-field. So change this like here:
public string FirstName { get { return _FirstName; } set { if (_FirstName != value) { _FirstName = value; // _FullName = value; RaisePropertyChanged("FirstName"); } } }
Now it works like a charm. ;-)
Thomas Claudius Huber
"If you can't make your app run faster, make it at least look & feel extremly fast"
My latest Pluralsight-courses:
XAML Layout in Depth
Windows Store Apps - Data Binding in Depth
twitter: @thomasclaudiush
homepage: www.thomasclaudiushuber.comStill I do not get my textboxes populated after I select a name from the listbox.
I think somewhere I need to call the database by passing the selected StudentID and get the FirstName and Address1 of that StudentID?
Thanks
Wednesday, September 2, 2015 8:55 PM -
Think about it.
How was Thomas ( or anyone ) supposed to know you hadn't got the address from the database?
Anyone trying to answer your questions only knows what you tell us.
Thursday, September 3, 2015 8:59 AM