Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have variable PersonnelName in class VehicleMainModel.
I want to get reference from object PersonnelObject of PersonnelMainViewModel.
When run my code following line throws Typecast exception:
PersonnelName = (bservableCollection) (PersonnelObject.Select(x => x.Name));
I don't understand how to resolve this. Even though both sides are list of string its not working. For your reference, I am attaching my both the classes here.
Please give working line for the same.
I have truncated unnecessary code for you.
vehicleMainViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Seris.Models;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Seris.Commands;
using Seris.ViewModels;
using System.Windows;
using System.Windows.Controls;
using System.Threading;
using System.ComponentModel;
using Seris.Views;
namespace Seris.ViewModels
{
public class VehicleMainViewModel : ObservableObject
{
#region Getters-Setters
// Static Variables...
private static VehicleMainViewModel _Instance;
public static VehicleMainViewModel getInstance
{
get
{
if(_Instance==null)
{
_Instance = new VehicleMainViewModel();
}
return _Instance;
}
}
private static AddVehicle _addVehicle;
public static AddVehicle addVehicle
{
get
{
return _addVehicle;
}
set
{
_addVehicle = value;
}
}
// Non-Static Variables...
// Error Components
. . .
private string _PersonnelNameSelected;
public string PersonnelNameSelected
{
get { return _PersonnelNameSelected; }
set
{
if (value == null || (!value.Equals(_PersonnelNameSelected)))
{
_PersonnelNameSelected = value;
EditText = _PersonnelNameSelected;
OnPropertyChanged("PersonnelNameSelected");
validateSpecificData(5);
}
}
}
private ObservableCollection<string> _PersonnelName;
public ObservableCollection<string> PersonnelName
{
get { return _PersonnelName; }
set
{
if (value != _PersonnelName)
{
_PersonnelName = value;
OnPropertyChanged("PersonnelName");
}
}
}
private ObservableCollection<PersonnelModel> _PersonnelObject;
public ObservableCollection<PersonnelModel> PersonnelObject
{
get { return _PersonnelObject; }
set
{
if (value != _PersonnelObject)
{
_PersonnelObject = value;
OnPropertyChanged("PersonnelObject");
}
}
}
private ObservableCollection<VehicleModel> _listItems;
public ObservableCollection<VehicleModel> ListItems
{
get { return _listItems; }
set
{
if (value == null || (!value.Equals(_listItems)))
{
_listItems = value;
}
}
}
// Other Variables
//Static Methods...
public static void showMessage(string message)
{
MessageBox.Show(message);
}
//Non-Static Methods...
. . .
public void clearAllData()
{
VehicleNo=null;
Model=null;
ManufacturingDate=null;
IUNo=null;
PersonnelNameSelected=null;
VehicleNo_Error = "";
Model_Error = "";
ManufacturingDate_Error = "";
IUNo_Error = "";
Personnel_Error= "";
}
#endregion
#region Constructors
public VehicleMainViewModel()
{
// Initialization
ListItems = new ObservableCollection<VehicleModel>();
PersonnelObject = PersonnelMainViewModel.getInstance.Personnel_List;
//This line gives error//
PersonnelName = (ObservableCollection<string>) (PersonnelObject.Select(x => x.Name));
// Setting Flags
ErrorMessage = "";
IsEnableReplaceButton = false;
// Commands Initialization
. . .
}
#endregion
}
}
PersonnelMainViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.ComponentModel;
using System.Windows.Markup;
using System.Windows.Data;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Documents;
using System.Windows.Controls.Primitives;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Diagnostics;
using System.Security;
using System.Collections.ObjectModel;
using Seris.Models;
using Seris.Views;
using Seris.ViewModels;
using Seris.Properties;
using Seris.Commands;
namespace Seris.ViewModels
{
public class PersonnelMainViewModel :ObservableObject
{
public ObservableCollection<PersonnelModel> Personnel_List;
private ObservableCollection<PersonnelModel> Personnel_copy;
public PersonnelModel model = new PersonnelModel();
public List<string> MyString;
public ICommand EditCommand;
public ICommand AddCommand;
public bool isRemove;
public static ObservableCollection<string> PersonNameList_Updating;
private static PersonnelMainViewModel _Instance;
public static PersonnelMainViewModel getInstance
{
get
{
if (_Instance == null)
{
_Instance = new PersonnelMainViewModel();
}
return _Instance;
}
}
public PersonnelMainViewModel()
{
MyString = new List<string>();
Personnel_copy = new ObservableCollection<PersonnelModel>();
isRemove = false;
Personnel_List = new ObservableCollection<PersonnelModel>
{
new PersonnelModel{ID=Guid.NewGuid(),Name="Mr.Joe",Gender="Male",Hospital="Poly Clinic",EMPID="abc 123",Capabilities="123",Position="Assistant",Title="Test",Status="General",ICNumber="IC 123",Roles="Test"},
new PersonnelModel{ID=Guid.NewGuid(),Name="Su Su",Gender="Female",Hospital="Clementi Clinic",EMPID="abc 1234",Capabilities="1234",Position="Security",Title="Test",Status="General",ICNumber="IC 1234",Roles="Test"},
new PersonnelModel{ID=Guid.NewGuid(),Name="Ms Tan",Gender="Female",Hospital="Bishan Clinic",EMPID="abc 1235",Capabilities="1235",Position="HR",Title="Test",Status="General",ICNumber="IC 1235",Roles="Test"},
};
Personnel_copy = new ObservableCollection<PersonnelModel>
{
new PersonnelModel{ID=Guid.NewGuid(),Name="Mr.Joe",Gender="Male",Hospital="Poly Clinic",EMPID="abc 123",Capabilities="123",Position="Assistant",Title="Test",Status="General",ICNumber="IC 123",Roles="Test"},
new PersonnelModel{ID=Guid.NewGuid(),Name="Su Su",Gender="Female",Hospital="Clementi Clinic",EMPID="abc 1234",Capabilities="1234",Position="Security",Title="Test",Status="General",ICNumber="IC 1234",Roles="Test"},
new PersonnelModel{ID=Guid.NewGuid(),Name="Ms Tan",Gender="Female",Hospital="Bishan Clinic",EMPID="abc 1235",Capabilities="1235",Position="HR",Title="Test",Status="General",ICNumber="IC 1235",Roles="Test"},
};
PersonNameList_Updating = new ObservableCollection<string> (Personnel_List.Select(x => x.Name));
_hos = new ObservableCollection<string> (Personnel_List.Select(x=>x.Hospital) );
EditCommand = new RelayCommand(Edit);
AddCommand = new RelayCommand(Add);
Removecommand = new RelayCommand(Remove);
SearchCommand = new RelayCommand(search);
//string[] textList = this.FindResource("Personnel_vm") as string[];
//ICollectionView view = CollectionViewSource.GetDefaultView(textList);
//new TextSearchFilter(view, this.txtSearch);
}
. . .
#endregion
. . .
}
}
VehicleModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using Seris.ViewModels;
namespace Seris.Models
{
public class VehicleModel : ObservableObject
{
#region Getters-Setters
private Guid? _UniqueNo;
public Guid? UniqueNo
{
get { return _UniqueNo; }
set
{
if (value != _UniqueNo)
{
_UniqueNo = value;
OnPropertyChanged("UniqueNo");
}
}
}
private string _VehicleNo;
public string VehicleNo
{
get { return _VehicleNo; }
set
{
if (value != _VehicleNo)
{
_VehicleNo = value.Trim();
OnPropertyChanged("VehicleNo");
}
}
}
private string _Model;
public string Model
{
get { return _Model; }
set
{
if (value != _Model)
{
_Model = value.Trim();
OnPropertyChanged("Model");
}
}
}
private DateTime? _ManufacturingDate;
public DateTime? ManufacturingDate
{
get { return _ManufacturingDate; }
set
{
if (value != _ManufacturingDate)
{
_ManufacturingDate = value;
OnPropertyChanged("ManufacturingDate");
}
}
}
private string _IUNo;
public string IUNo
{
get { return _IUNo; }
set
{
if (value != _IUNo)
{
_IUNo = value.Trim();
OnPropertyChanged("IUNo");
}
}
}
private string _PersonnelNameSelected;
public string PersonnelNameSelected
{
get { return _PersonnelNameSelected; }
set
{
if (value != _PersonnelNameSelected)
{
_PersonnelNameSelected = value;
OnPropertyChanged("PersonnelNameSelected");
}
}
}
#endregion
#region Methods
// Validating Forms
private void ValidateAllData(Object sender)
{
bool errorFlag=false;
if (!Validate_VehicleNo())
{
errorFlag = true;
}
if (!Validate_Model())
{
errorFlag = true;
}
if (!Validate_ManufacturingDate())
{
errorFlag = true;
}
if (!Validate_IUNo())
{
errorFlag = true;
}
if (!Validate_PersonnelName()) // For Future Enhancement
{
errorFlag = true;
}
// Personnel Remaining..........//
if (errorFlag)
throw (new Exception("Invalid Details\nClick on Help for details"));
}
public void ValidateSpecificData(Object sender, int ErrorObj)
{
bool errorFlag = false;
if (sender is VehicleMainViewModel)
{
VehicleMainViewModel senderObject = (VehicleMainViewModel)sender;
errorFlag = false;
switch(ErrorObj)
{
case 1:
if (!Validate_VehicleNo())
{
senderObject.VehicleNo_Error = "3 Caps alphabet following 4 numericals only";
errorFlag = true;
}
else
senderObject.VehicleNo_Error = "";
break;
case 2:
if (!Validate_Model())
{
senderObject.Model_Error = "Mandatory Field";
errorFlag = true;
}
else
senderObject.Model_Error = "";
break;
case 3:
if (!Validate_ManufacturingDate())
{
senderObject.ManufacturingDate_Error = "Can't be blank or future Date";
errorFlag = true;
}
else
senderObject.ManufacturingDate_Error = "";
break;
case 4:
if (!Validate_IUNo())
{
senderObject.IUNo_Error = "10 digits numerical only";
errorFlag = true;
}
else
senderObject.IUNo_Error = "";
break;
case 5:
if (!Validate_PersonnelName())
{
senderObject.Personnel_Error = "Mandatory Fvnield";
errorFlag = true;
}
else
senderObject.Personnel_Error = "";
break;
}
}
}
// To Check Regular Expressions
public bool matchRE(string stringToMatch, string regularExpression)
{
Regex regex = new Regex(#regularExpression);
Match match = regex.Match(stringToMatch);
if (match.Success)
return (true);
else
return (false);
}
#region Validate Methods
public bool Validate_VehicleNo()
{
if (VehicleNo == null || VehicleNo.Trim().Length==0)
return false;
if (matchRE(VehicleNo,"[A-Zz-z][A-Zz-z0-9]{6}"))
return true;
else
return false;
}
public bool Validate_Model()
{
if (Model == null || Model.Trim().Length==0)
return false;
if(Model!=null || Model.Length==0)
return true;
else
return false;
}
public bool Validate_ManufacturingDate()
{
if (ManufacturingDate == null || ManufacturingDate.ToString().Trim().Length == 0)
return false;
if( ManufacturingDate > DateTime.Now )
return false;
return true;
}
public bool Validate_IUNo()
{
if (IUNo == null || IUNo.Trim().Length==0)
return false;
if(matchRE(IUNo,"[0-9]{10}"))
return true;
else
return false;
}
public bool Validate_PersonnelName()
{
if (PersonnelNameSelected == null || PersonnelNameSelected.Trim().Length == 0)
return false;
else
return true;
}
#endregion
#endregion
#region Constructors
public VehicleModel(string VehicleNo, string Model, DateTime? ManufacturingDate, string IUNo, string PersonnelNameSelected)
{
this.UniqueNo = Guid.NewGuid();
this.VehicleNo = VehicleNo;
this.Model = Model;
this.ManufacturingDate = ManufacturingDate;
this.IUNo = IUNo;
this.PersonnelNameSelected = PersonnelNameSelected;
ValidateAllData(this);
}
public VehicleModel()
{
UniqueNo = null;
VehicleNo = null;
Model = null;
ManufacturingDate = null;
IUNo = null;
PersonnelNameSelected = null;
}
#endregion
}
}
AddVehicle.xaml
<Window x:Class="Seris.Views.AddVehicle"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AddVehicle" Height="650" Width="750"
xmlns:l="clr-namespace:Seris.ViewModels">
<Grid>
<Label Content="Add Vehicle" HorizontalAlignment="Left" Height="27" Margin="261,8,0,0" VerticalAlignment="Top" Width="85" FontWeight="Bold" FontSize="12"/>
<Label Content="SERIS CAD" HorizontalAlignment="Left" Height="30" Margin="61,5,0,0" VerticalAlignment="Top" Width="84" FontWeight="Bold"/>
<Menu x:Name="AddNewPersonnel" HorizontalAlignment="Left" Height="32" Margin="10,32,-329,0" VerticalAlignment="Top" Width="611">
<MenuItem Header="Manage Vehicle >>" Margin="0" />
<MenuItem Header="Add Vehicle >>" Margin="0" />
</Menu>
<GroupBox Header="Vehicle Information" HorizontalAlignment="Left" Height="267" Margin="10,64,0,0" VerticalAlignment="Top" Width="611" FontWeight="Bold" FontSize="12"/>
<Canvas HorizontalAlignment="Left" Height="352" Margin="18,91,0,0" VerticalAlignment="Top" Width="603">
<Label Content="Vehical No" HorizontalAlignment="Left" Height="27" Width="104" Margin="10,10,0,232"/>
<TextBox Name="VehicalNo_Text" Height="27" Width="193" TextWrapping="Wrap" MaxLength="7" Text="{Binding VehicleNo, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="85,10,0,239" />
<Label Name="VehicleNoError_Label" Foreground="Red" Content="{Binding VehicleNo_Error, UpdateSourceTrigger=PropertyChanged}" Height="27" Width="275" Canvas.Left="323" Canvas.Top="10"/>
<Label Content="Model" HorizontalAlignment="Left" Height="27" Width="104" RenderTransformOrigin="0.49,-2.185" Canvas.Left="10" Canvas.Top="62"/>
<TextBox Name="Model_Text" Height="27" Width="193" TextWrapping="Wrap" MaxLength="15" Text="{Binding Model, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Canvas.Left="85" Canvas.Top="62" />
<Label x:Name="ModelError_Label" Foreground="Red" Content="{Binding Model_Error, UpdateSourceTrigger=PropertyChanged}" Height="27" Width="275" Canvas.Left="323" Canvas.Top="62"/>
<Label Content="Manu. Date" HorizontalAlignment="Left" Height="27" Width="104" Canvas.Left="10" Canvas.Top="112"/>
<DatePicker x:Name="ManufacturingDate_DateTime" SelectedDate="{Binding ManufacturingDate, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="193" Height="25" Canvas.Left="85" Canvas.Top="114"/>
<Label Name="ManufacturingDateError_Label" Foreground="Red" Content="{Binding ManufacturingDate_Error, UpdateSourceTrigger=PropertyChanged}" Height="27" Width="275" Canvas.Left="323" Canvas.Top="112"/>
<Label Content="IU No" HorizontalAlignment="Left" Height="27" Width="104" Canvas.Left="10" Canvas.Top="157"/>
<TextBox Height="27" Width="193" Name="IUNO_Text" TextWrapping="Wrap" MaxLength="10" Text="{Binding IUNo, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Canvas.Left="85" Canvas.Top="157"/>
<Label Name="IUError_Label" Foreground="Red" Content="{Binding IUNo_Error, UpdateSourceTrigger=PropertyChanged}" Height="27" Width="275" Canvas.Left="323" Canvas.Top="157"/>
<Label Content="Personnel" HorizontalAlignment="Left" Height="27" Width="104" Canvas.Left="10" Canvas.Top="198"/>
<ComboBox x:Name="Personnel_Combo" SelectedValue="{Binding PersonnelNameSelected, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding PersonnelName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Height="27" Width="193" Canvas.Left="85" Canvas.Top="198"/>
<Label Name="Personnel_Label" Foreground="Red" Content="{Binding Personnel_Error, UpdateSourceTrigger=PropertyChanged}" Height="27" Width="275" Canvas.Left="318" Canvas.Top="198"/>
</Canvas>
<Label x:Name="Error_Label" Content="{Binding ErrorMessage, UpdateSourceTrigger=PropertyChanged}" Foreground="Red" HorizontalAlignment="Left" Width="236" Margin="187,345,0,200"/>
<Button Name="Help" Visibility="{Binding HelpVisibility, UpdateSourceTrigger=PropertyChanged}" Command="{Binding OpenHelpWindow_Command}" Height="50" Width="50" Margin="562,377,80,143">
<Button.DataContext>
<l:VehicleHelpViewModel />
</Button.DataContext>
<Image Height="45" Width="45" Source="../Images/help.jpg"/>
</Button>
<Button Name="Save_Button" Command="{Binding SaveButton_Command}" CommandParameter="save" Height="28" Width="81" Content="Save" Margin="265,392,346,150"/>
<TextBlock Name="Preview" Text="{Binding EditText, UpdateSourceTrigger=PropertyChanged}" Margin="13,377,542,168"/>
</Grid>
</Window>
since Select method returns an IEnumerable<T> you may perhaps do this way
IEnumerable<string> personNames = PersonnelObject.Select(x => x.Name);
PersonnelName = new ObservableCollection<string>();// optional if not initialized
foreach(string pName in personNames )
{
PersonnelName.Add(pName);
}
as the Select method returns an IEnumerable which will not propagate changes made in source collection you may perhaps solve the issue via binding itself
here is a sample for combobox
<ComboBox ItemsSource="{Binding PersonnelObject}"
DisplayMemberPath="Name" />
in above example ComboBox binds to the source collection PersonnelObject while displaying the Name property
you may perhaps revise the binding as
<ComboBox x:Name="Personnel_Combo"
SelectedValue="{Binding PersonnelNameSelected, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding PersonnelObject}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
HorizontalAlignment="Left"
Height="27"
Width="193"
Canvas.Left="85"
Canvas.Top="198" />
note that I have changed the ItemsSource to bind to PersonnelObject and used the SelectedValuePath and DisplayMemberPath property to display and store the correct value.
You can create ObservableCollection by initializing it like this
PersonnelName = new ObservableCollection(PersonnelObject.Select(x => x.Name));
Or
PersonnelName = new ObservableCollection<string>(PersonnelObject.Select(x => x.Name));
Related
I'm totally new to MVVM and I've been going through a lot of online posts regarding how do I implement CRUD operations and properly bind SQLite database data to WPF controls like Datagrid, Combobox, Textbox, Button etc. but struggling to find what I need. Also, for someone who is new to MVVM pattern it seems pretty intimidating to say the least.
Anyways, coming to the point, I've found this post online and tried my best to make it work for SQLite databases but struggling at the moment.
My project structure looks like this:
and the relevant files as follows:
StudentRepository.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SQLite;
using System.Linq;
using TestWpfMVVM.Model;
namespace TestWpfMVVM.DataAccess
{
public class StudentRepository
{
private StudentEntities studentContext = null;
public StudentRepository()
{
studentContext = new StudentEntities();
}
public Student Get(int id)
{
return studentContext.Students.Find(id);
}
public List<Student> GetAll()
{
return studentContext.Students.ToList();
}
public void AddStudent(Student student)
{
if (student != null)
{
studentContext.Students.Add(student);
studentContext.SaveChanges();
}
}
public void UpdateStudent(Student student)
{
var studentFind = this.Get(student.stdId);
if (studentFind != null)
{
studentFind.stdName = student.stdName;
studentFind.stdContact = student.stdContact;
studentFind.stdAge = student.stdAge;
studentFind.stdAddress = student.stdAddress;
studentContext.SaveChanges();
}
}
public void RemoveStudent(int id)
{
var studObj = studentContext.Students.Find(id);
if (studObj != null)
{
studentContext.Students.Remove(studObj);
studentContext.SaveChanges();
}
}
}
}
Student.cs
using System;
namespace TestWpfMVVM.Model
{
public class Student
{
public int stdId { get; set; }
public string stdName { get; set; }
public int stdAge { get; set; }
public string stdAddress { get; set; }
public string stdContact { get; set; }
}
}
StudentRecord.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TestWpfMVVM.ViewModel;
namespace TestWpfMVVM.Model
{
public class StudentRecord : ViewModelBase
{
private int _id;
public int Id
{
get
{
return _id;
}
set
{
_id = value;
OnPropertyChanged("Id");
}
}
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
OnPropertyChanged("Name");
}
}
private int _age;
public int Age
{
get
{
return _age;
}
set
{
_age = value;
OnPropertyChanged("Age");
}
}
private string _address;
public string Address
{
get
{
return _address;
}
set
{
_address = value;
OnPropertyChanged("Address");
}
}
private string _contact;
public string Contact
{
get
{
return _contact;
}
set
{
_contact = value;
OnPropertyChanged("Contact");
}
}
private ObservableCollection<StudentRecord> _studentRecords;
public ObservableCollection<StudentRecord> StudentRecords
{
get
{
return _studentRecords;
}
set
{
_studentRecords = value;
OnPropertyChanged("StudentRecords");
}
}
}
}
RelayCommand.cs
using System;
using System.Windows.Input;
namespace TestWpfMVVM.ViewModel
{
public class RelayCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
}
StudentViewModel.cs
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
using TestWpfMVVM.DataAccess;
using TestWpfMVVM.Model;
namespace TestWpfMVVM.ViewModel
{
public class StudentViewModel
{
private ICommand _saveCommand;
private ICommand _resetCommand;
private ICommand _editCommand;
private ICommand _deleteCommand;
private StudentRepository _repository;
private Student _studentEntity = null;
public StudentRecord StudentRecord { get; set; }
public ICommand ResetCommand
{
get
{
if (_resetCommand == null)
_resetCommand = new RelayCommand(param => ResetData(), null);
return _resetCommand;
}
}
public ICommand SaveCommand
{
get
{
if (_saveCommand == null)
_saveCommand = new RelayCommand(param => SaveData(), null);
return _saveCommand;
}
}
public ICommand EditCommand
{
get
{
if (_editCommand == null)
_editCommand = new RelayCommand(param => EditData((int)param), null);
return _editCommand;
}
}
public ICommand DeleteCommand
{
get
{
if (_deleteCommand == null)
_deleteCommand = new RelayCommand(param => DeleteStudent((int)param), null);
return _deleteCommand;
}
}
public StudentViewModel()
{
_studentEntity = new Student();
_repository = new StudentRepository();
StudentRecord = new StudentRecord();
GetAll();
}
public void ResetData()
{
StudentRecord.Name = string.Empty;
StudentRecord.Id = 0;
StudentRecord.Address = string.Empty;
StudentRecord.Contact = string.Empty;
StudentRecord.Age = 0;
}
public void DeleteStudent(int id)
{
if (MessageBox.Show("Confirm delete of this record?", "Student", MessageBoxButton.YesNo)
== MessageBoxResult.Yes)
{
try
{
_repository.RemoveStudent(id);
MessageBox.Show("Record successfully deleted.");
}
catch (Exception ex)
{
MessageBox.Show("Error occured while saving. " + ex.InnerException);
}
finally
{
GetAll();
}
}
}
public void SaveData()
{
if (StudentRecord != null)
{
_studentEntity.stdName = StudentRecord.Name;
_studentEntity.stdAge = StudentRecord.Age;
_studentEntity.stdAddress = StudentRecord.Address;
_studentEntity.stdContact = StudentRecord.Contact;
try
{
if (StudentRecord.Id <= 0)
{
_repository.AddStudent(_studentEntity);
MessageBox.Show("New record successfully saved.");
}
else
{
_studentEntity.stdId = StudentRecord.Id;
_repository.UpdateStudent(_studentEntity);
MessageBox.Show("Record successfully updated.");
}
}
catch (Exception ex)
{
MessageBox.Show("Error occured while saving. " + ex.InnerException);
}
finally
{
GetAll();
ResetData();
}
}
}
public void EditData(int id)
{
var model = _repository.Get(id);
StudentRecord.Id = model.stdId;
StudentRecord.Name = model.stdName;
StudentRecord.Age = (int)model.stdAge;
StudentRecord.Address = model.stdAddress;
StudentRecord.Contact = model.stdContact;
}
public void GetAll()
{
StudentRecord.StudentRecords = new ObservableCollection<StudentRecord>();
_repository.GetAll().ForEach(data => StudentRecord.StudentRecords.Add(new StudentRecord()
{
Id = data.stdId,
Name = data.stdName,
Address = data.stdAddress,
Age = Convert.ToInt32(data.stdAge),
Contact = data.stdContact
}));
}
}
}
ViewModelBase.cs
using System.ComponentModel;
namespace TestWpfMVVM.ViewModel
{
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
MainWindow.xaml.cs
using System.Windows;
using TestWpfMVVM.ViewModel;
namespace TestWpfMVVM.View
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new StudentViewModel();
}
}
}
MainWindow.xaml
<Window x:Class="TestWpfMVVM.View.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:TestWpfMVVM.View"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel Orientation="Vertical">
<GroupBox Header="Student Form" Margin="10">
<Grid Height="150">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Content="Name" HorizontalAlignment="Left"
VerticalContentAlignment="Center" Grid.Column="0" Grid.Row="0"/>
<TextBox Grid.Row="0" Grid.Column="1" x:Name="TextBoxName" Height="27"
Text="{Binding Path=StudentRecord.Name, Mode=TwoWay}" Margin="5" Width="300" HorizontalAlignment="Left"/>
<Label Content="Age" HorizontalAlignment="Left" VerticalContentAlignment="Center"
Grid.Row="1" Grid.Column="0"/>
<TextBox Grid.Row="1" Grid.Column="1" x:Name="TextBoxAge" Height="27"
Text="{Binding Path=StudentRecord.Age, Mode=TwoWay}" Margin="5" Width="70" HorizontalAlignment="Left"/>
<TextBlock Grid.Row="1" Grid.Column="1" x:Name="TextBlockId"
Visibility="Hidden" Text="{Binding Path=StudentRecord.Id, Mode=TwoWay}"/>
<Label Content="Address" HorizontalAlignment="Left" VerticalContentAlignment="Center"
Grid.Row="2" Grid.Column="0" />
<TextBox Grid.Row="2" Grid.Column="1" x:Name="TextBoxAddress" Height="27"
Text="{Binding Path=StudentRecord.Address, Mode=TwoWay}" Margin="5" Width="300" HorizontalAlignment="Left"/>
<Label Content="Contact" HorizontalAlignment="Left" VerticalContentAlignment="Center"
Grid.Row="3" Grid.Column="0" />
<TextBox Grid.Row="3" Grid.Column="1" x:Name="TextBoxContact" Height="27"
Text="{Binding Path=StudentRecord.Contact, Mode=TwoWay}" Margin="5" Width="300" HorizontalAlignment="Left"/>
</Grid>
</GroupBox>
<StackPanel Height="40" Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="ButtonSave" Content="Save" Height="30" Width="80"
Command="{Binding SaveCommand}"/>
<Button x:Name="ButtonCancel" Content="Cancel" Height="30" Width="80"
Command="{Binding ResetCommand}" Margin="5,0,10,0"/>
</StackPanel>
<StackPanel Height="210">
<DataGrid x:Name="DataGridStudents" AutoGenerateColumns="False"
ItemsSource="{Binding StudentRecord.StudentRecords}" CanUserAddRows="False" Height="200" Margin="10">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Id}" Visibility="Hidden"/>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" Width="100" IsReadOnly="True"/>
<DataGridTextColumn Header="Age" Binding="{Binding Path=Age}" Width="50" IsReadOnly="True"/>
<DataGridTextColumn Header="Address" Binding="{Binding Path=Address}" Width="180" IsReadOnly="True"/>
<DataGridTextColumn Header="Contact" Binding="{Binding Path=Contact}" Width="125" IsReadOnly="True"/>
<DataGridTemplateColumn Width="50">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Select" x:Name="ButtonEdit" CommandParameter="{Binding Path=Id}"
Command="{Binding Path=DataContext.EditCommand,RelativeSource={RelativeSource FindAncestor,
AncestorType=Window}}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="50">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Delete" x:Name="ButtonDelete" CommandParameter="{Binding Path=Id}"
Command="{Binding Path=DataContext.DeleteCommand, RelativeSource={RelativeSource FindAncestor,
AncestorType=Window}}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</StackPanel>
</Window>
Now in the post, inside the Model folder, they added an ADO.NET Entity Data Model that connects to the Students table in the database and named it StudentModel while changing connectionstring name to StudentEntities.
But, I have a local SQLite database, how do I change that and what other things I need to change to make this app work. Currently I have only the error Error CS0246 The type or namespace name 'StudentEntities' could not be found (are you missing a using directive or an assembly reference?) which is understandable.
I know this may be a lot to ask but any help will be highly appreciated as I'm trying to make this work for quite some time now!
EDIT
After further checking I've updated StudentRepository as below
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SQLite;
using System.Linq;
using TestWpfMVVM.Model;
namespace TestWpfMVVM.DataAccess
{
public class StudentRepository
{
public void ExecuteWrite(string query, Dictionary<string, object> args)
{
//setup the connection to the database
using (var con = new SQLiteConnection(#"Data Source=./Students.db;"))
{
con.Open();
//open a new command
using (var cmd = new SQLiteCommand(query, con))
{
//set the arguments given in the query
foreach (var pair in args)
{
cmd.Parameters.AddWithValue(pair.Key, pair.Value);
}
cmd.ExecuteNonQuery();
}
}
}
public DataTable Execute(string query, Dictionary<string, object> args)
{
if (string.IsNullOrEmpty(query.Trim()))
return null;
using (var con = new SQLiteConnection(#"Data Source=./Students.db;"))
{
con.Open();
using (var cmd = new SQLiteCommand(query, con))
{
foreach (KeyValuePair<string, object> entry in args)
{
cmd.Parameters.AddWithValue(entry.Key, entry.Value);
}
var da = new SQLiteDataAdapter(cmd);
var dt = new DataTable();
da.Fill(dt);
da.Dispose();
return dt;
}
}
}
public void AddStudent(Student student)
{
const string query = "INSERT INTO tabStud(Name, Age, Address, Contact) VALUES(#stdName, #stdAge, #stdAddress, #stdContact)";
var args = new Dictionary<string, object>
{
{"#stdName", student.stdName},
{"#stdAge", student.stdAge},
{"#stdAddress", student.stdAddress},
{"#stdContact", student.stdContact}
};
ExecuteWrite(query, args);
}
public void UpdateStudent(Student student)
{
const string query = "UPDATE tabStud SET Name = #stdName, Age = #stdAge, Address = #stdAddress, Contact = #stdContact WHERE Id = #stdId";
var args = new Dictionary<string, object>
{
{"#stdId", student.stdId},
{"#stdName", student.stdName},
{"#stdAge", student.stdAge},
{"#stdAddress", student.stdAddress},
{"#stdContact", student.stdContact}
};
ExecuteWrite(query, args);
}
public void RemoveStudent(Student student)
{
const string query = "Delete from tabStud WHERE Id = #stdId";
var args = new Dictionary<string, object>
{
{"#stdId", student.stdId}
};
ExecuteWrite(query, args);
}
public Student Get(int id)
{
var student = new Student();
var query = "SELECT * FROM tabStud WHERE Id = #stdId";
var args = new Dictionary<string, object>
{
{"#stdId", student.stdId}
};
DataTable dt = Execute(query, args);
if (dt == null || dt.Rows.Count == 0)
{
return null;
}
student = new Student
{
stdId = Convert.ToInt32(dt.Rows[0]["Id"]),
stdName = Convert.ToString(dt.Rows[0]["Name"]),
stdAge = Convert.ToInt32(dt.Rows[0]["Age"]),
stdAddress = Convert.ToString(dt.Rows[0]["Address"]),
stdContact = Convert.ToString(dt.Rows[0]["Contact"])
};
return student;
}
public List<Student> GetAll()
{
List<Student> students = new List<Student>();
var student = new Student();
var query = "SELECT * FROM tabStud";
var args = new Dictionary<string, object>
{
{"#stdId", student.stdId}
};
DataTable dt = Execute(query, args);
if (dt == null || dt.Rows.Count == 0)
{
return null;
}
student = new Student
{
stdId = Convert.ToInt32(dt.Rows[0]["Id"]),
stdName = Convert.ToString(dt.Rows[0]["Name"]),
stdAge = Convert.ToInt32(dt.Rows[0]["Age"]),
stdAddress = Convert.ToString(dt.Rows[0]["Address"]),
stdContact = Convert.ToString(dt.Rows[0]["Contact"])
};
students.Add(student);
return students;
}
}
}
and StudentViewModel as under
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
using TestWpfMVVM.DataAccess;
using TestWpfMVVM.Model;
namespace TestWpfMVVM.ViewModel
{
public class StudentViewModel
{
private ICommand _saveCommand;
private ICommand _resetCommand;
private ICommand _editCommand;
private ICommand _deleteCommand;
private StudentRepository _repository;
private Student _studentEntity = null;
public StudentRecord StudentRecord { get; set; }
public ICommand ResetCommand
{
get
{
if (_resetCommand == null)
_resetCommand = new RelayCommand(param => ResetData(), null);
return _resetCommand;
}
}
public ICommand SaveCommand
{
get
{
if (_saveCommand == null)
_saveCommand = new RelayCommand(param => SaveData(), null);
return _saveCommand;
}
}
public ICommand EditCommand
{
get
{
if (_editCommand == null)
_editCommand = new RelayCommand(param => EditData((int)param), null);
return _editCommand;
}
}
public ICommand DeleteCommand
{
get
{
if (_deleteCommand == null)
_deleteCommand = new RelayCommand(param => DeleteStudent((int)param), null);
return _deleteCommand;
}
}
public StudentViewModel()
{
_studentEntity = new Student();
_repository = new StudentRepository();
StudentRecord = new StudentRecord();
GetAll();
}
public void ResetData()
{
StudentRecord.Name = string.Empty;
StudentRecord.Id = 0;
StudentRecord.Address = string.Empty;
StudentRecord.Contact = string.Empty;
StudentRecord.Age = 0;
}
public void DeleteStudent(int id)
{
if (MessageBox.Show("Confirm delete of this record?", "Student", MessageBoxButton.YesNo)
== MessageBoxResult.Yes)
{
try
{
var model = _repository.Get(id);
_repository.RemoveStudent(model);
MessageBox.Show("Record successfully deleted."); ;
}
catch (Exception ex)
{
MessageBox.Show("Error occured while saving. " + ex.InnerException);
}
finally
{
GetAll();
}
}
}
public void SaveData()
{
if (StudentRecord != null)
{
_studentEntity.stdName = StudentRecord.Name;
_studentEntity.stdAge = StudentRecord.Age;
_studentEntity.stdAddress = StudentRecord.Address;
_studentEntity.stdContact = StudentRecord.Contact;
try
{
if (StudentRecord.Id <= 0)
{
_repository.AddStudent(_studentEntity);
MessageBox.Show("New record successfully saved.");
}
else
{
_studentEntity.stdId = StudentRecord.Id;
_repository.UpdateStudent(_studentEntity);
MessageBox.Show("Record successfully updated.");
}
}
catch (Exception ex)
{
MessageBox.Show("Error occured while saving. " + ex.InnerException);
}
finally
{
GetAll();
ResetData();
}
}
}
public void EditData(int id)
{
var model = _repository.Get(id);
StudentRecord.Id = model.stdId;
StudentRecord.Name = model.stdName;
StudentRecord.Age = (int)model.stdAge;
StudentRecord.Address = model.stdAddress;
StudentRecord.Contact = model.stdContact;
}
public void GetAll()
{
StudentRecord.StudentRecords = new ObservableCollection<StudentRecord>();
_repository.GetAll().ForEach(data => StudentRecord.StudentRecords.Add(new StudentRecord()
{
Id = data.stdId,
Name = data.stdName,
Address = data.stdAddress,
Age = Convert.ToInt32(data.stdAge),
Contact = data.stdContact
}));
}
}
}
Now I'm able to run the project and also can add data to the table using the Save button. But after window loading I can only see the first row in the datagrid and not all of the rows. Furthermore, when I click on the Select and Delete button I get the errors respectively
I believe there is some problem in the Get(id) method but not sure how to fix...
Also, this is what my database table looks like
You should reimplement your own version of StudentRepository and delete the StudentEntities and use SqLite instead.
start by experimenting with some code to connect to the database, then select a full table and map it to a student object. SqLite has the ability to use generic and can fill you Student object if the Properties match with the name of the column in your database.
Ok Jayanta,
below is extract of my own code that you can get inspiration of and report it to your student repo:
public IEnumerable<Equity> GetListOfStocksOfMarket(string exchange)
{
string query = string.Format("SELECT * from " + Tables.ASSETS_TABLE + " WHERE ExchangeMic='{0}'", exchange);
Log(query);
var command = _connection.CreateCommand(query);
var equities = command.ExecuteQuery<Equity>();
IEnumerable<Equity> ret = equities.OrderBy(x=>x.InstrumentName).ToList();
return ret;
}
private SQLiteConnection _connection;
public bool Connect()
{
_connection = new SQLiteConnection(DATABASE_FILE_NAME);
_isConnected = true;
RepoYield = new RepoYield(_connection);
return true;
}
I offered some code that utilizes the SQLite namespaces / context here
SQL statement for creating new data into three tables at once c#
Like you creating some sort of wrapper repository, adjust as you need. I have example context of ensuring data types / sizes, etc.
You could even apply GENERICS based on each table structure you wanted to apply CRUD to. You can see the querying to the connected database context also simplifies pulling data using PARAMETERIZED QUERIES vs string manipulated which could allow SQL-Injection.
Data types as bound per your example would not need to be "converted" because the binding to the underlying structure that may be numeric based would only allow the value to be stored if it WERE numeric to begin with. I could expand more if you had any questions, but hopefully with the view model, and view context you have already, creating your own wrapper/repository using SQLite directly might help a bit more.
I have a small program, because I'm new, my program is to bring data from sql sever to textbox via combobox option and use the value shown in that textbox to calculate the +
I have made it to the step of putting up the data, now thanks to you to help me with the value calculation in the textbox, thank you for your help.
xaml code :
<Window x:Class="comboboxapp1.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:comboboxapp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:SimpleMath x:Key="MyFriends"/>
</Window.Resources>
<Grid>
<Label Content="code" HorizontalAlignment="Left" Margin="38,52,0,0"
VerticalAlignment="Top" Width="46" Height="23"/>
<Label Content="pieces" HorizontalAlignment="Left" Margin="38,126,0,0"
VerticalAlignment="Top" Width="46" Height="23"/>
<Label Content="layers" HorizontalAlignment="Left" Margin="38,196,0,0"
VerticalAlignment="Top" Width="46" Height="30"/>
<Label Content="production pieces" HorizontalAlignment="Left"
Margin="0,278,0,0" VerticalAlignment="Top" Width="108" Height="25"/>
<TextBox x:Name="txtcode"
Text="{Binding Txtcode, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left" Height="23" Margin="124,52,0,0"
TextWrapping="Wrap" VerticalAlignment="Top" Width="141"/>
<TextBox x:Name="txtpieces"
Text="{Binding Txtpieces, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left" Height="23"
Margin="124,133,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="141"/>
<TextBox x:Name="txtlayers"
Text="{Binding Txtlayers,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left" Height="23"
Margin="124,203,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="141"/>
<TextBox x:Name="txtproductionpieces"
Text="{Binding Txtproductionpieces,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left" Height="23" Margin="124,280,0,0"
TextWrapping="Wrap" VerticalAlignment="Top" Width="141"/>
<ComboBox x:Name="comboBox1" ItemsSource="{Binding Source={StaticResource MyFriends}}"
HorizontalAlignment="Left" Margin="418,52,0,0" VerticalAlignment="Top"
Width="319" Height="36" SelectionChanged="ComboBox1_SelectionChanged"/>
<TextBox x:Name="txtseccond"
Text="{Binding Txtseccond,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left" Height="23"
Margin="124,345,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="141"/>
<Label Content="seccond" HorizontalAlignment="Left" Margin="38,345,0,0"
VerticalAlignment="Top" Width="46" Height="23"/>
<TextBlock Text="{Binding A, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left" Margin="418,133,0,0" TextWrapping="Wrap"
VerticalAlignment="Top" Height="23" Width="248"/>
<TextBox Text="{Binding No1,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left" Height="21" Margin="426,210,0,0"
TextWrapping="Wrap" VerticalAlignment="Top" Width="303"/>
</Grid>
</Window>
C# code:
using System;
using System.Collections.Generic;
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;
using System.Data.SqlClient;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace comboboxapp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public SimpleMath Formular { get; set; }
public object SelectedValue { get; private set; }
public MainWindow()
{
Formular = new SimpleMath()
{
Txtcode = 0,
Txtpieces = 0,
Txtlayers = 0,
Txtproductionpieces = 0,
Txtseccond = 0,
};
InitializeComponent();
DataContext = Formular;
Fillcombobox();
}
private void MainWindow_Load(object sender, EventArgs e)
{
}
public void Fillcombobox()
{
SqlConnection con = new SqlConnection("Data Source=LEAN-22\\SQLEXPRESS;Initial
Catalog=LUAT;Integrated Security=True");
string sql = " select * from comboboxnew ";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader myreader;
try
{
con.Open();
myreader = cmd.ExecuteReader();
while (myreader.Read())
{
string sname = myreader.GetInt32(0).ToString();
comboBox1.Items.Add(sname);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public class SimpleMath : INotifyPropertyChanged
{
private int no1;
public int No1
{
get { return no1; }
set
{
no1 = value;
OnPropertyChanged("No1");
OnPropertyChanged("A");
}
}
private int txtcode;
public int Txtcode
{
get { return txtcode; }
set
{
txtcode = value;
OnPropertyChanged("Txtcode");
OnPropertyChanged("A");
}
}
private int txtpieces;
public int Txtpieces
{
get { return txtpieces; }
set
{
txtpieces = value;
OnPropertyChanged("Txtcode");
OnPropertyChanged("A");
}
}
private int txtlayers;
public int Txtlayers
{
get { return txtlayers; }
set
{
txtlayers = value;
OnPropertyChanged("Txtlayers");
OnPropertyChanged("A");
}
}
private int txtproductionpieces;
public int Txtproductionpieces
{
get { return txtproductionpieces; }
set
{
txtproductionpieces = value;
OnPropertyChanged("Txtproductionpieces");
OnPropertyChanged("A");
}
}
private int txtseccond;
public int Txtseccond
{
get { return txtseccond; }
set
{
txtseccond = value;
OnPropertyChanged("Txtseccond");
OnPropertyChanged("A");
}
}
public double A => No1;
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName()] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
private void ComboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SqlConnection con = new SqlConnection("Data Source=LEAN-22\\SQLEXPRESS;Initial
Catalog=LUAT;Integrated Security=True");
// string sql = " select * from comboboxnew where code = '" + comboBox1.Text+ "';";
string sql = " select * from comboboxnew where code = '" + comboBox1.SelectedItem +
"';";
//Console.WriteLine(comboBox1.Text);
//MessageBox.Show(comboBox1.Text);
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader myreader;
try
{
con.Open();
myreader = cmd.ExecuteReader();
while (myreader.Read())
{
string code = myreader.GetInt32(0).ToString();
string pieces = myreader.GetInt32(1).ToString();
string layers = myreader.GetInt32(2).ToString();
string productionpieces = myreader.GetInt32(3).ToString();
string seccond = myreader.GetInt32(4).ToString();
txtcode.Text = code;
//txtcode.Text =SelectedValue;
txtpieces.Text = pieces;
//txtpieces.Text = "New value";
txtlayers.Text = layers;
//txtlayers.Text = "New value";
txtproductionpieces.Text = productionpieces;
//txtproductionpieces.Text = "New value";
txtseccond.Text = seccond;
//txtseccond.Text = "New value";
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
From what I understand, you simply want to sum those five values into the TextBox, right?
If so, you can do that multiple ways...
One:
Have a property in the SimpleMath class that is the sum of the other values, and bind that to the TextBox. You would have to update the sum property whenever any of those five other ones updates.
Two:
You could use the IMultiValueConverter to sum the values without having any more properties in the SimpleMath class. It's done like this:
You create a class that implements the IMultiValueConverter inteface
public class SumConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values.Cast<int>()?.Sum()?.ToString();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return null;
}
}
And use it in XAML like this
<TextBox>
<TextBox.Resources>
<local:SumConverter x:Key="SumConverter"/>
</TextBox.Resources>
<TextBox.Text>
<MultiBinding Converter="{StaticResource SumConverter}">
<Binding Path="Text" ElementName="OtherTextBox1" />
<Binding Path="Text" ElementName="OtherTextBox2" />
<Binding Path="Text" ElementName="OtherTextBox3" />
<Binding Path="Text" ElementName="OtherTextBox4" />
<Binding Path="Text" ElementName="OtherTextBox5" />
</MultiBinding>
</TextBox.Text>
</Control>
Hope this helps
EDIT
I've made a test project to show you the full code for both of my suggested solutions, here it is:
Solution one
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
namespace StackOverflowTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new SimpleMath();
}
}
public class SimpleMath : INotifyPropertyChanged
{
private int _numberOne;
public int NumberOne
{
get => _numberOne;
set
{
_numberOne = value;
OnPropertyChanged();
CalculateSum();
}
}
private int _numberTwo;
public int NumberTwo
{
get => _numberTwo;
set
{
_numberTwo = value;
OnPropertyChanged();
CalculateSum();
}
}
private int _numberThree;
public int NumberThree
{
get => _numberThree;
set
{
_numberThree = value;
OnPropertyChanged();
CalculateSum();
}
}
private int _numberSum;
public int NumberSum
{
get => _numberSum;
set
{
_numberSum = value;
OnPropertyChanged();
}
}
private void CalculateSum()
{
NumberSum = NumberOne + NumberTwo + NumberThree;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName()] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
<Window x:Class="StackOverflowTest.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:StackOverflowTest"
mc:Ignorable="d"
Title="MainWindow" Height="200" Width="200">
<StackPanel>
<TextBox x:Name="TxtOne" HorizontalAlignment="Stretch" Text="{Binding NumberOne}" Margin="10,10,10,0"/>
<TextBox x:Name="TxtTwo" HorizontalAlignment="Stretch" Text="{Binding NumberTwo}" Margin="10,10,10,0"/>
<TextBox x:Name="TxtThree" HorizontalAlignment="Stretch" Text="{Binding NumberThree}" Margin="10,10,10,0"/>
<TextBlock HorizontalAlignment="Center" Text="{Binding NumberSum}" Margin="10,10,10,0"/>
</StackPanel>
</Window>
Solution two
using System;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Data;
using System.Collections.Generic;
namespace StackOverflowTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new SimpleMath();
}
}
public class SimpleMath : INotifyPropertyChanged
{
private int _numberOne;
public int NumberOne
{
get => _numberOne;
set
{
_numberOne = value;
OnPropertyChanged();
}
}
private int _numberTwo;
public int NumberTwo
{
get => _numberTwo;
set
{
_numberTwo = value;
OnPropertyChanged();
}
}
private int _numberThree;
public int NumberThree
{
get => _numberThree;
set
{
_numberThree = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName()] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class SumConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var numbers = new List<int>();
foreach (var item in values)
{
if(item is string stringValue)
{
try
{
numbers.Add(System.Convert.ToInt32(stringValue));
}
catch (Exception)
{
Console.WriteLine("Oops, not a number...");
}
}
}
return numbers.Sum().ToString();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return null;
}
}
}
<Window x:Class="StackOverflowTest.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:StackOverflowTest"
mc:Ignorable="d"
Title="MainWindow" Height="200" Width="200">
<StackPanel>
<TextBox x:Name="TxtOne" HorizontalAlignment="Stretch" Text="{Binding NumberOne}" Margin="10,10,10,0"/>
<TextBox x:Name="TxtTwo" HorizontalAlignment="Stretch" Text="{Binding NumberTwo}" Margin="10,10,10,0"/>
<TextBox x:Name="TxtThree" HorizontalAlignment="Stretch" Text="{Binding NumberThree}" Margin="10,10,10,0"/>
<TextBlock HorizontalAlignment="Center" Margin="10,10,10,0">
<TextBlock.Resources>
<local:SumConverter x:Key="SumConverter"/>
</TextBlock.Resources>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource SumConverter}">
<Binding Path="Text" ElementName="TxtOne" />
<Binding Path="Text" ElementName="TxtTwo" />
<Binding Path="Text" ElementName="TxtThree" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</Window>
Here's how it looks
Very new to WPF coding using MVVM. Tried making a simple calculator in WPF using MVVM. But unable to trigger the Icommand in the below code.If possible help me in this. Grateful if anybody can help me out.
View Code:
<Window x:Class="MVVMCalculator.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:MVVMCalculator"
mc:Ignorable="d"
Title="Calculator" Height="350" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="85"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Text="{Binding Display, Mode=OneWay}" IsReadOnly="True" TextWrapping="Wrap"
Grid.Row="0" Background="#E2E2E2" Margin="0,10,0,0" VerticalAlignment="Top"
Height="75" Width="250" HorizontalAlignment="Center" FontSize="22" FontWeight="Bold"
TextAlignment="Right">
<TextBox.Effect>
<DropShadowEffect/>
</TextBox.Effect>
</TextBox>
<ItemsControl Grid.Row="1" ItemsSource="{Binding Buttns}" Margin="15,15,15,10">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="5" Rows="4" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Txt, Mode=TwoWay}" Command="{Binding Enter_number}"
FontSize="18" FontWeight="Bold" Height="50" Width="50" Background="#eef2f3"
BorderBrush="Black" BorderThickness="1.0" Name="number">
<Button.Effect>
<DropShadowEffect/>
</Button.Effect>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
ViewModel Code:
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.Input;
namespace MVVMCalculator
{
class ViewModel : INotifyPropertyChanged
{
Buttons btn = new Buttons();
private decimal operand1;
private decimal operand2;
private string operation;
private decimal result;
private string display;
private bool newDisplayRequired = false;
ObservableCollection<Buttons> buttns;
public ObservableCollection<Buttons> Buttns
{
get { return buttns; }
set { buttns = value; }
}
public decimal Result
{
get { return result; }
}
public decimal Operand1
{
get { return operand1; }
set { operand1 = value; }
}
public decimal Operand2
{
get { return operand2; }
set { operand2 = value; }
}
public string Operation
{
get { return operation; }
set { operation = value; }
}
public string Display
{
get { return display; }
set { display = value;
OnPropertyChanged("Display");
}
}
public ViewModel()
{
buttns = new ObservableCollection<Buttons>
{
new Buttons("1"), new Buttons("2"), new Buttons("3"),
new Buttons("C"), new Buttons("Back"), new Buttons("4"),
new Buttons("5"), new Buttons("6"), new Buttons("CE"),
new Buttons("%"), new Buttons("7"), new Buttons("8"),
new Buttons("9"), new Buttons("/"), new Buttons("*"),
new Buttons("0"), new Buttons("."), new Buttons("+"),
new Buttons("-"), new Buttons("=")
};
display = "0";
operand1 = 0;
operand2 = 0;
operation = "";
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private ICommand enter_number;
public ICommand Enter_number
{
get
{
if(enter_number==null)
{
enter_number = new DelegateCommand<string>(MyAction, _canExecute);
}
return enter_number;
}
}
private static bool _canExecute(string button)
{
return true;
}
public void MyAction(string btn)
{
switch(btn)
{
case "C":
display = "0";
operand1 = 0;
operand2 = 0;
//operation = "";
break;
case ".":
if (!display.Contains("."))
{
Display = display + ".";
}
break;
case "Back":
if (display.Length > 1)
Display = display.Substring(0, display.Length - 1);
else Display = "0";
break;
default:
if (display == "0" || newDisplayRequired)
Display = btn;
else
Display = display + btn;
break;
}
}
}
}
Buttons Class:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MVVMCalculator
{
class Buttons:INotifyPropertyChanged
{
private string txt;
public string Txt
{
get { return txt; }
set { txt = value; }
}
public Buttons(string a)
{
txt = a;
}
public Buttons()
{
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Xaml.cs:
using System;
using System.Collections.Generic;
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 MVVMCalculator
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new ViewModel();
}
}
}
Since the Enter_number property is defined in the ViewModel class you need to use a {RelativeSource} to be able to bind to it:
<Button Content="{Binding Txt, Mode=TwoWay}"
Command="{Binding DataContext.Enter_number, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
FontSize="18" FontWeight="Bold" Height="50" Width="50" Background="#eef2f3"
BorderBrush="Black" BorderThickness="1.0" Name="number">
<Button.Effect>
<DropShadowEffect/>
</Button.Effect>
</Button>
The default DataContext of the Button is the current Buttons object in the ItemsSource collection of the ItemsControl and that's why your binding fails.
I populate a ListBox in a page with some data from a webservice, a list of comment replies. On that same page is a textbox and a post button that allows users to post a reply to a comment while on the RepliesPage. When I run the app and post a reply, the List isn't updated immediately, until I navigate away from the page and navigate back to the page will I see the new reply added to the List. How do I get around this?.
Page's XAML
<phone:PhoneApplicationPage
x:Class="CeFlix.Views.RepliesPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
xmlns:cimbalinoBehaviors="clr-namespace:Cimbalino.Phone.Toolkit.Behaviors;assembly=Cimbalino.Phone.Toolkit"
xmlns:cimbalinoHelpers="clr-namespace:Cimbalino.Phone.Toolkit.Helpers;assembly=Cimbalino.Phone.Toolkit.Background"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
shell:SystemTray.IsVisible="True"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
xmlns:UserControl="clr-namespace:CeFlix.UserControls">
<i:Interaction.Behaviors>
<cimbalinoBehaviors:ApplicationBarBehavior>
<cimbalinoBehaviors:ApplicationBarIconButton x:Name="postReply"
Text="post"
IconUri="/Assets1/AppBar/send.text.png"
IsEnabled="True"
Command="{Binding UserSubmitReplyCommand,Mode=TwoWay}"/>
<!--<cimbalinoBehaviors:ApplicationBarIconButton x:Name="home"
Text="home"
IconUri="/Assets1/AppBar/basecircle.png"
IsEnabled="True"
Click="home_Click"/>-->
</cimbalinoBehaviors:ApplicationBarBehavior>
</i:Interaction.Behaviors>
<!--<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar>
<shell:ApplicationBarIconButton x:Name="postReply"
IconUri="/Assets1/AppBar/send.text.png"
IsEnabled="True" Text="Post"
Click="UserSubmitReplyCommand"/>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>-->
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="#0C426B">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Orientation="Horizontal" Grid.Row="0" Style="{StaticResource ContentHeaderStyle}" Height="72">
<Button Command="{Binding Path=ClickShowPopUpCommand,Mode=TwoWay}" Style="{StaticResource ButtonStyle}" Height="65">
<StackPanel Orientation="Horizontal">
<Image Source="/Images/logo.png" Height="45" Margin="20,0,0,0"/>
<TextBlock Text="REPLIES" Margin="20,0,0,0" Style="{StaticResource PhoneTextTitle2Style}" Foreground="#0C426B" FontWeight="Bold" FontFamily="Segoe WP Black"/>
</StackPanel>
</Button>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" >
<ListBox x:Name="lbxReplies"
ItemsSource="{Binding ReplyList,Mode=TwoWay}"
Margin="0,0,-12,0"
>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="400"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Ellipse Width="50" Height="50" Margin="8" VerticalAlignment="Top">
<Ellipse.Fill>
<ImageBrush ImageSource="{Binding profile_pic}"/>
</Ellipse.Fill>
</Ellipse>
<Border Grid.ColumnSpan="2" Grid.Row="0" HorizontalAlignment="Stretch" BorderBrush="Black" BorderThickness="0,0,0,0.5"/>
<StackPanel Grid.Column="1">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="16" Text="{Binding username}" Foreground="#FFF8DE7E" FontFamily="Consolas" />
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Left"
FontSize="16" Text="{Binding comment}"
TextWrapping="Wrap"
TextOptions.DisplayColorEmoji="True"
TextOptions.TextHintingMode="Animated"
TextTrimming="WordEllipsis" Foreground="White" FontFamily="Consolas" />
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
<StackPanel Orientation="Horizontal" Grid.Row="2">
<TextBox x:Name="replyTextBox"
Width="475"
Text="{Binding Message,Mode=TwoWay}"
TextChanged="replyTextBox_TextChanged"
BorderThickness="0"
GotFocus="replyTextBox_GotFocus">
<TextBox.Background>
<ImageBrush ImageSource="/Assets/watermark2.png"/>
</TextBox.Background>
<TextBox.InputScope>
<InputScope>
<InputScopeName NameValue="Text" />
</InputScope>
</TextBox.InputScope>
</TextBox>
<
</StackPanel>
<UserControl:DataLoading x:Name="loaderForReplies" Grid.RowSpan="2" Visibility="{Binding LoaderForReplyVisibility}" />
</Grid>
Code behind
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string parameter = this.NavigationContext.QueryString["parameter"];
BaseViewModel.SelectedCommentID = parameter;
}
private async void ContentPanel_Loaded(object sender, RoutedEventArgs e)
{
await repliesViewModel.GetReplyList();
this.DataContext = this.repliesViewModel;
lbxReplies.ItemsSource = null;
lbxReplies.ItemsSource = repliesViewModel.ReplyList;
}
And this is the ViewModel code
using CeFlix.Common;
using CeFlix.Entities;
using CeFlix.OtherEntities;
using Microsoft.Phone.Tasks;
using Microsoft.Xna.Framework.Media;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Xml.Linq;
using Windows.Storage;
namespace CeFlix.ViewModels
{
public class RepliesViewModel : BaseViewModel
{
#region Properties
private UserStatusData userStatusData;
public UserStatusData UserStatusData
{
get
{
return this.userStatusData;
}
set
{
SetProperty(ref userStatusData, value);
}
}
private string message;
public string Message
{
get
{
return message;
}
set
{
SetProperty(ref message, value);
}
}
private Visibility replyListControlVisibility = Visibility.Visible;
public Visibility ReplyListControlVisibility
{
get
{
return this.replyListControlVisibility;
}
set
{
SetProperty(ref replyListControlVisibility, value);
}
}
private Visibility userReplyPopUpOpen;
public Visibility UserReplyPopupOpen
{
get
{
return this.userReplyPopUpOpen;
}
set
{
SetProperty(ref this.userReplyPopUpOpen, value);
}
}
private Visibility loaderForReplyVisibility = Visibility.Collapsed;
public Visibility LoaderForReplyVisibility
{
get
{
return this.loaderForReplyVisibility;
}
set
{
SetProperty(ref this.loaderForReplyVisibility, value);
}
}
private Visibility signInPopUpVisibility = Visibility.Collapsed;
public Visibility SignInPopUpVisibility
{
get
{
return this.signInPopUpVisibility;
}
set
{
SetProperty(ref this.signInPopUpVisibility, value);
}
}
private ObservableCollection<Reply> replyList;
public ObservableCollection<Reply> ReplyList
{
get
{
return replyList;
}
set
{
SetProperty(ref this.replyList, value);
}
}
private ReplyDetails replyDetailsData;
public ReplyDetails ReplyDetailsData
{
get
{
return this.replyDetailsData;
}
set
{
SetProperty(ref this.replyDetailsData, value);
}
}
// Comment
private CommentDetails comment;
public CommentDetails Comment
{
get
{
return this.comment;
}
set
{
SetProperty(ref this.comment, value);
}
}
private Comment selectedComment;
public Comment SelectedComment
{
get
{
return this.selectedComment;
}
set
{
SetProperty(ref this.selectedComment, value);
if (value != null)
{
BaseViewModel.SelectedCommentID = this.selectedComment.id;
this.GetCommentDetail();
this.GetReplyList();
}
}
}
private CommentDetails commentsDetailsData;
public CommentDetails CommentsDetailsData
{
get
{
return this.commentsDetailsData;
}
set
{
SetProperty(ref this.commentsDetailsData, value);
}
}
private CeFlix.Entities.Detail videoDetail;
public CeFlix.Entities.Detail VideoDetail
{
get
{
return this.videoDetail;
}
set
{
SetProperty(ref this.videoDetail, value);
}
}
private CeFlix.Entities.VideoDetails videoDetailData;
public CeFlix.Entities.VideoDetails VideoDetailData
{
get
{
return this.videoDetailData;
}
set
{
SetProperty(ref this.videoDetailData, value);
}
}
#endregion
#region Constructor
public RepliesViewModel()
{
this.ReplyList = new ObservableCollection<Reply>();
}
#endregion
#region Single Instance could be replacement for Singleton that I know of
private static RepliesViewModel currentInstance = null;
public static RepliesViewModel GetSingleInstance()
{
if (currentInstance == null)
{
currentInstance = new RepliesViewModel();
}
return currentInstance;
}
#endregion
#region Delegate Commands
private DelegateCommand goHome;
public DelegateCommand GoHome
{
get
{
if (goHome == null)
goHome = new DelegateCommand(GoHomeCommandClick);
return goHome;
}
}
private DelegateCommand userSubmitReplyCommand;
public DelegateCommand UserSubmitReplyCommand
{
get
{
if (userSubmitReplyCommand == null)
userSubmitReplyCommand = new DelegateCommand(UserSubmitReplyCommandClick);
return userSubmitReplyCommand;
}
}
#endregion
#region Methods
private void GoHomeCommandClick()
{
BaseViewModel.NavigationService.NavigateToPage(Entities.Enums.Views.DashboardPage);
}
public async Task GetCommentDetail()
{
try
{
string Api_Url = string.Format(Constants.LoadComment_API, BaseViewModel.SelectedCommentID) + "?timestamp" + DateTime.Now.ToString();
if (BaseViewModel.HelperClass.IsInternet())
{
var response = await BaseViewModel.HelperClass.Get(Api_Url);
var selectedCommentDetails = JSONHelper.DeserializeFromJson<CeFlix.Entities.CommentDetails>(response);
// this.SelectedComment = selectedCommentDetails.Comments;
foreach (Comment item in selectedCommentDetails.Comments)
{
this.SelectedComment = item;
}
}
else
{
await System.Threading.Tasks.Task.Delay(1000);
MessageBoxResult msgResult = MessageBox.Show(Constants.NETWORK_ERROR, Constants.NETWORK_ERROR_TITLE, MessageBoxButton.OKCancel);
if (msgResult == MessageBoxResult.OK)
{
await GetCommentDetail();
}
else
{
Application.Current.Terminate();
}
}
}
catch (Exception)
{
BaseViewModel.ShowErrorMessage();
}
}
public async Task GetReplyList()
{
try
{
// LoaderForReplyVisibility = Visibility.Visible; // add this later, it think it should control display of usercontrol for replying
string Api_Url = string.Format(Constants.LoadCommentReplies_API, BaseViewModel.SelectedCommentID) + "?timestamp" + DateTime.Now.ToString();
if (BaseViewModel.HelperClass.IsInternet())
{
var response = await BaseViewModel.HelperClass.Get(Api_Url);
this.ReplyDetailsData = JSONHelper.DeserializeFromJson<ReplyDetails>(response);
if (ReplyDetailsData.Error.ToLower() == "none")
{
this.ReplyList = this.ReplyDetailsData.details.replies.ToObservableCollection();
LoaderForReplyVisibility = Visibility.Collapsed;
}
}
else
{
await System.Threading.Tasks.Task.Delay(1000);
MessageBoxResult msgResult = MessageBox.Show(Constants.NETWORK_ERROR, Constants.NETWORK_ERROR_TITLE, MessageBoxButton.OKCancel);
if (msgResult == MessageBoxResult.OK)
{
await GetReplyList();
}
else
{
Application.Current.Terminate();
}
}
}
catch (Exception)
{
BaseViewModel.ShowErrorMessage();
}
}
public async Task GetVideoDetail()
{
try
{
string Api_Url = string.Format(Constants.VideoDetail_API, BaseViewModel.SelectedVideoID) + "?timestamp" + DateTime.Now.ToString();
if (BaseViewModel.HelperClass.IsInternet())
{
var response = await BaseViewModel.HelperClass.Get(Api_Url);
this.VideoDetailData = JSONHelper.DeserializeFromJson<CeFlix.Entities.VideoDetails>(response);
if (VideoDetailData.Error.ToLower() == "none")
{
this.VideoDetail = this.VideoDetailData.Details.FirstOrDefault();
// this.GetVideoViews();
}
}
else
{
await System.Threading.Tasks.Task.Delay(1000);
MessageBoxResult msgResult = MessageBox.Show(Constants.NETWORK_ERROR, Constants.NETWORK_ERROR_TITLE, MessageBoxButton.OKCancel);
if (msgResult == MessageBoxResult.OK)
{
await GetVideoDetail();
}
else
{
Application.Current.Terminate();
}
}
}
catch (Exception)
{
BaseViewModel.ShowErrorMessage();
}
}
private async void UserSubmitReplyCommandClick()
{
try
{
if (BaseViewModel.HelperClass.IsInternet())
{
if (!string.IsNullOrEmpty(this.Message))
{
HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(Constants.Reply_API);
webRequest.Method = "POST";
webRequest.UserAgent = "immtv.loveworldapis.com";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.BeginGetRequestStream(new AsyncCallback(GetRequestSubmitReplyStreamCallback), webRequest);
}
else
{
MessageBox.Show("First Enter Reply");
}
}
else
{
await System.Threading.Tasks.Task.Delay(1000);
MessageBoxResult msgResult = MessageBox.Show(Constants.NETWORK_ERROR, Constants.NETWORK_ERROR_TITLE, MessageBoxButton.OKCancel);
if (msgResult == MessageBoxResult.OK)
{
UserSubmitReplyCommandClick();
}
else
{
Application.Current.Terminate();
}
}
}
catch (Exception)
{
BaseViewModel.ShowErrorMessage();
}
}
// settle down to analyze this method because it's the body of the POST for posting a reply
void GetRequestSubmitReplyStreamCallback(IAsyncResult callbackResult)
{
try
{
string requestBody = "";
HttpWebRequest webRequest = (HttpWebRequest)callbackResult.AsyncState;
Stream postStream = webRequest.EndGetRequestStream(callbackResult);
// requestBody = "email=" + BaseViewModel.UserEmailId + "&reply=" + Message + "&video_id=" + BaseViewModel.SelectedVideoID;
requestBody = "commentID=" + BaseViewModel.SelectedCommentID + "&comment=" + Message + "&email=" + BaseViewModel.UserEmailId;
byte[] byteArray = Encoding.UTF8.GetBytes(requestBody);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
webRequest.BeginGetResponse(new AsyncCallback(GetResponseUserSubmitReplyStreamCallback), webRequest);
}
catch (Exception)
{
BaseViewModel.ShowErrorMessage();
}
}
// and this too
void GetResponseUserSubmitReplyStreamCallback(IAsyncResult calldatabackResult)
{
try
{
HttpWebRequest request = (HttpWebRequest)calldatabackResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(calldatabackResult);
using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
{
string result = httpWebStreamReader.ReadToEnd();
UserStatusData = JSONHelper.DeserializeFromJson<CeFlix.Entities.UserStatusData>(result);
}
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
if (UserStatusData.status == "OK")
{
// this.GetReplyList();
this.Message = string.Empty;
MessageBox.Show("Reply Added Successfully");
RepliesViewModel repliesViewModel = RepliesViewModel.GetSingleInstance();
ReplyListControlVisibility = Visibility.Collapsed;
repliesViewModel.GetReplyList();
ReplyListControlVisibility = Visibility.Visible;
}
});
}
catch (Exception)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
BaseViewModel.ShowErrorMessage();
});
}
}
#endregion
}
}
and this inside the BaseViewModel, which the RepliesViewModel inherits from
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
{
if (object.Equals(storage, value)) return false;
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
I have tried several things like calling ListBox.Items.Clear(), this returned a debugger error, I tried ListBox.ItemsSource = null and bind it again, still dint work. What do i need to do to trigger a refresh and update the data displayed in the ListBox immediately?
To fix your problem change your code behind just to set the data context in your constructor:
public MyPageConstructor() // Your page constructor
{
this.DataContext = new RepliesViewModel(); // Or any other way how you create your view model
}
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string parameter = this.NavigationContext.QueryString["parameter"];
BaseViewModel.SelectedCommentID = parameter;
}
private async void ContentPanel_Loaded(object sender, RoutedEventArgs e)
{
await repliesViewModel.GetReplyList();
//this.DataContext = this.repliesViewModel;
//lbxReplies.ItemsSource = null; *removed*
//lbxReplies.ItemsSource = repliesViewModel.ReplyList;
}
and on your ListBox bind the ItemsSource:
<ListBox x:Name="lbxReplies"
ItemsSource="{Binding ReplyList}"
Margin="0,0,-12,0"
>
EDIT: I think you may have a bug in your GetResponseUserSubmitReplyStreamCallback method:
RepliesViewModel repliesViewModel = RepliesViewModel.GetSingleInstance();
repliesViewModel.GetReplyList();
If your RepliesViewModel.GetSingleInstance() method creates a new instance then this code will do nothing useful.
If the GetResponseUserSubmitReplyStreamCallback method is in your page class then you probably want to only call
repliesViewModel.GetReplyList();
You need to create a new kind of list inheriting from ObservableCollection (looks like you already have done that) :
public class MyItems:ObservableCollection<Item>
{
}
Also you need MyItemsInstance to comply with INotifyPropertyChanged "pattern"
public class YourViewModelClass:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public MyItems MyItemsInstance
{
get
{
return this.customerNameValue;
}
set
{
if (value != this.customerNameValue)
{
this.customerNameValue = value;
NotifyPropertyChanged();
}
}
}
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Then you can fill up your list instance calling the service.
This works if your are using MVVM in the right way. so in your XAML you need to bind the list source with your list instance , I can see this part in your code.
Take a look to the ItemsSource property
<ListBox x:Name="lbxReplies" ItemsSource="{Binding MyItemsInstanceInModel}"
Margin="0,0,-12,0"
>
<!--All other stuff-->
</ListBox>
If the binding is OK, once you modify MyItemsInstanceInModel contents or even if you assign a new instance the UI should be refreshed by itself.
Add lbxReplies.Items.Refresh() after emptying the listbox(lbxReplies.Items.Clear() or lbxReplies.ItemsSource = null).
Or
Since, lisReplyList is binded to lbxReplies. So, Call ReplyList.Clear() instead of lbxReplies.Items.Clear() or lbxReplies.ItemsSource = null.
I am working on WPF C#, MVVM Model. I have issue with Save_Button in View. All the things like getter, setter, RelayCommand initialization are working, just nothing happens when I click on 'Save' Buton. So it seems like Binding from View to ViewModel is not working. I am providing here only necessary files of View, ViewModel and Command part. Kindly help.
VehicalForm.xaml
<Window x:Class="Seris.VehicalForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<WrapPanel Orientation="Vertical" Margin="10 " >
<Label Content="Vehical No" HorizontalAlignment="Left"/>
<TextBox Name="VehicalNo_Text" Height="23" TextWrapping="Wrap" Text="TextBox" HorizontalAlignment="Left"/>
<Label Content="Model" HorizontalAlignment="Left"/>
<TextBox Name="Model_Text" Height="23" TextWrapping="Wrap" Text="TextBox" HorizontalAlignment="Left" />
<Label Content="Manufacturing Date" HorizontalAlignment="Left"/>
<DatePicker/>
<Label Content="IU No" HorizontalAlignment="Left"/>
<TextBox Height="23" Name="IUNO_Text" TextWrapping="Wrap" Text="TextBox" HorizontalAlignment="Left"/>
<Label Content="Personnel" HorizontalAlignment="Left"/>
<ComboBox Name="Personnel_Combo" HorizontalAlignment="Left" Width="116"/>
<Separator Height="20" RenderTransformOrigin="0.5,0.5" Width="16"/>
<Button Name="Save_Button" Command="{Binding SaveToList}" Content="Save" Width="66"/>
<ListView Height="294" Width="371" >
<ListView.View>
<GridView>
<GridViewColumn Header="lkj"/>
<GridViewColumn Header="lkj"/>
<GridViewColumn Header="lkj"/>
</GridView>
</ListView.View>
</ListView>
</WrapPanel>
VehicalForm.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Seris
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class VehicalForm : Window
{
public VehicalForm()
{
InitializeComponent();
}
}
}
VehicalMainViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Seris.Models;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Seris.Commands;
using Seris.ViewModels;
namespace Seris.ViewModels
{
public class VehicalMainViewModel : ObservableObject
{
ObservableCollection<VehicalModel> listItems = new ObservableCollection<VehicalModel>();
#region Getter-Setter
private string _VehicalNo;
public string VehicalNo
{
get { return _VehicalNo; }
set
{
if (value != _VehicalNo)
{
_VehicalNo = value.Trim();
OnPropertyChanged("ProductName");
}
}
}
private string _Model;
public string Model
{
get { return _Model; }
set
{
if (value != _Model)
{
_Model = value.Trim();
OnPropertyChanged("ProductName");
}
}
}
private DateTime _ManufacturingDate;
public DateTime ManufacturingDate
{
get { return _ManufacturingDate; }
set
{
if (value != _ManufacturingDate)
{
_ManufacturingDate = value;
OnPropertyChanged("ProductName");
}
}
}
private string _IUNo;
public string IUNo
{
get { return _IUNo; }
set
{
if (value != _IUNo)
{
_IUNo = value.Trim();
OnPropertyChanged("ProductName");
}
}
}
private string _PersonnelName;
public string PersonnelName
{
get { return _PersonnelName; }
set
{
if (value != _PersonnelName)
{
_PersonnelName = value.Trim();
OnPropertyChanged("ProductName");
}
}
}
#endregion
private ICommand _saveButton_Command;
public ICommand SaveButton_Command
{
get { return _saveButton_Command; }
set { _saveButton_Command = value; }
}
public void SaveToList(object o1)
{
listItems.Add(new VehicalModel(VehicalNo,Model,ManufacturingDate,IUNo,PersonnelName));
}
public void RemoveFromList()
{
}
public VehicalMainViewModel()
{
VehicalModel vm=new VehicalModel();
SaveButton_Command = new RelayCommand(new Action<object>(SaveToList));
}
}
}
RelayCommand.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
namespace Seris.Commands
{
public class RelayCommand : ICommand
{
private Action<object> _action;
public RelayCommand(Action<object> action)
{
_action = action;
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action(parameter);
}
}
}
try in XAML
<Button Name="Save_Button" Command="{Binding SaveButton_Command}" … />
You tried to Bind to the Method instead of the Command.
<Button Name="Save_Button" Command="{Binding SaveButton_Command}" />
Have you set the DataContext in on your VehicalForm-Window?
public VehicalForm()
{
InitializeComponent();
this.DataContext = new VehicalMainViewModel();
}