How to update UI when ObservableCollection updated? - c#

I have simple app, where ObservableCollection is updating in code and when new item added the UI is updated too. To update UI i am using a Dispatcher which is passed as a property to ViewModel. My code is works, but i don't know right i am or not.
Here is the code:
MainWindow.xaml.cs
/// <summary>
/// Логика взаимодействия для MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
MainWindowViewModel model = new MainWindowViewModel();
public MainWindow()
{
InitializeComponent();
this.DataContext = model;
this.model.dispatcher = this.Dispatcher;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string url = urlToCheck.Text;
Task task = new Task(() =>
{
model.GetUrls(url);
});
task.ContinueWith((previousTask) =>
{
label.Content = "Все ссылки собраны.";
},
TaskScheduler.FromCurrentSynchronizationContext());
label.Content = "Идёт сбор ссылок...";
task.Start();
}
}
MainWindowViewModel.cs
class MainWindowViewModel
{
public ObservableCollection<Url> Urls { get; set; }
public bool NeedToGetResponseForChildUrls { get; set; }
public bool NeedToDeletePreviousResults { get; set; }
public Dispatcher dispatcher;
some code.....................
**and something like this i am updating ObservableCollection:**
if (NeedToDeletePreviousResults)
{
dispatcher.Invoke(() =>
{
Urls.Clear();
});
}
Url.cs
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace CheckUrl
{
public class Url : INotifyPropertyChanged
{
private string _absoluteUrl;
public string AbsoluteUrl
{
get { return _absoluteUrl; }
set
{
if (_absoluteUrl != value)
{
_absoluteUrl = value;
OnPropertyChanged("AbsoluteUrl");
}
}
}
private int _responseStatusCode;
public int ResponseStatusCode
{
get { return _responseStatusCode; }
set
{
if (_responseStatusCode != value)
{
_responseStatusCode = value;
OnPropertyChanged("ResponseStatusCode");
}
}
}
private string _responseStatusDescription;
public string ResponseStatusDescription
{
get { return _responseStatusDescription; }
set
{
if (_responseStatusDescription != value)
{
_responseStatusDescription = value;
OnPropertyChanged("ResponseStatusDescription");
}
}
}
public enum Status { Working, Broken };
private Status _urlStatus;
public Status UrlStatus
{
get { return _urlStatus; }
set
{
if (_urlStatus != value)
{
_urlStatus = value;
OnPropertyChanged("UrlStatus");
}
}
}
private string _color;
public string Color
{
get { return _color; }
set
{
if (_color != value)
{
_color = value;
OnPropertyChanged("Color");
}
}
}
private ObservableCollection<ChildUrl> _childUrlsValue = new ObservableCollection<ChildUrl>();
public ObservableCollection<ChildUrl> ChildUrls
{
get
{
return _childUrlsValue;
}
set
{
_childUrlsValue = value;
}
}
/// <summary>
/// Конструктор класса Url.
/// </summary>
public Url(string absoluteUrl, int responseStatusCode, string responseStatusDescription, Status urlStatus, string color)
{
this.AbsoluteUrl = absoluteUrl;
this.ResponseStatusCode = responseStatusCode;
this.ResponseStatusDescription = responseStatusDescription;
this.UrlStatus = urlStatus;
this.Color = color;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

ObservableCollection can update your UI automaticaly by using binding. Use a list of ObservableCollection and add / remove items from is. Make the ObservableCollection as a public property.In the MainWindow constructor write:
This.DataContext=This;
Use binding to your listBox / any other control you need to show the items on. ObservableCollection allready implement IINotifyPropertyChanged in it. Once you change the items in your ObservableCollection your UI will change as well.

Related

Unable to bind my DatePicker to my ViewModel

I'm trying to implement a datepicker and bind it to a model I've created.
I've made a global tournament object in App.xaml.cs:
private Tournament _tournament;
public Tournament tournament {
get { return _tournament; }
set { _tournament = value; OnPropertyChanged("tournament"); }
}
And I've made an OnStartup override to launch my windows:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
//setup score
score = new Score();
// Tournament setup
tournament = new Tournament();
tournament.GamesToWin = 1;
tournament.Games = new List<Game>(1);
tournament.Players = new List<Player>(2) { new Player(), new Player() };
//tournament.TimeAndDate = new DateTime(2021, 11, 22);
tournament.Winner = null;
// Initializing the UserInput
UserInput userInput = new UserInput();
UserInputWindowViewModel userinputViewModel = new UserInputWindowViewModel();
userInput.DataContext = userinputViewModel;
// Opening the UserInput Window
bool? res = userInput.ShowDialog();
// If the UserInput Window is closed, open the next Window
if (res == true)
{
// Opening the MainWindow
MainWindow main = new MainWindow();
main.Show();
}
else
{
Shutdown();
}
}
Model.cs (Tournament.cs):
public class Tournament : INotifyPropertyChanged
{
private Player _winner;
private DateTime? _timeAndDate;
private List<Player> _players;
public List<Player> Players
{
get { return _players; }
set { _players = value; OnPropertyChanged("Players"); }
}
private List<Game> _games;
public List<Game> Games
{
get { return _games; }
set { _games = value; OnPropertyChanged("Games"); }
}
private int _gamesToWin;
public int GamesToWin
{
get { return _gamesToWin; }
set { _gamesToWin = value; OnPropertyChanged("GamesToWin"); }
}
public Player Winner
{
get { return _winner; }
set { _winner = value; OnPropertyChanged("Winner"); }
}
public DateTime? TimeAndDate
{
get { return _timeAndDate; }
set { _timeAndDate = value; OnPropertyChanged("TimeAndDate"); }
}
#region PropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
ViewModel.cs (UserInputWindowViewModel.cs):
public class UserInputWindowViewModel
{
// Calling the current app to access the tournament object globally
public App currentApp = Application.Current as App;
#region The players object
private List<Player> _players;
public List<Player> Players
{
get { return _players; }
set { _players = value; }
}
#endregion
#region The DateTime object
private DateTime? _dateTime;
public DateTime? TournamentDateTime
{
get { return _dateTime; }
set { _dateTime = value; }
}
#endregion
public UserInputWindowViewModel()
{
Tournament tournament = currentApp.tournament;
Players = tournament.Players;
TournamentDateTime = new DateTime(2021, 11, 22);
tournament.TimeAndDate = TournamentDateTime;
//TournamentDateTime = tournament.TimeAndDate;
}
#region ICommand Members
private ICommand mUpdater;
public ICommand UpdateCommand
{
get
{
if (mUpdater == null)
mUpdater = new Updater();
return mUpdater;
}
set
{
mUpdater = value;
}
}
private class Updater : ICommand
{
public bool CanExecute(object parameter) => true;
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
}
}
#endregion
}
Inside my window (UserInput.xaml) I have the following Datepicker:
<DatePicker SelectedDate="{Binding TournamentDateTime, Mode=TwoWay}"/>
I've set the date inside my viewmodel to 22-11-2021 as test, but when I change the date, it's not changing. What am I doing wrong?
EDIT: I also tried the OnPropertyChanged in the ViewModel, which didn't work
You forgot to implement INotifyPropertyChanged under UserInputWindowViewModel.cs.
public class UserInputWindowViewModel : INotifyPropertyChanged
{
}
Also make sure you are triggering PropertyChanged event in property setter, it's important for two-way binding
public DateTime? TournamentDateTime
{
get { return _dateTime; }
set
{
_dateTime = value;
OnPropertyChanged(nameof(TournamentDateTime);
}
}
I'd also would suggest not to access Application directly from a view model, better pass tournament object as a dependency to a view model as soon it would be better separation of concerns
I managed to fix my problem:
I made a small function to update my global model:
public void updateModel(DateTime? s)
{
currentApp.tournament.TimeAndDate = s;
}
I've added this small bit of code to my getter/setter inside my viewmodel (notice I used DateTime.Now to set it to the current date):
private DateTime? _dateTime = DateTime.Now;
public DateTime? TournamentDateTime
{
get { return _dateTime; }
set { _dateTime = value; updateModel(value); }
}
This fixed all my problems with the datepicker. And I didn't have to use INotifyPropertychanged inside my viewmodel because my model already had it implemented.

How to work with a model in viewModel

I'm having a problem with using MVVM for a Xamarin project.
I can not refresh the user interface if one of my objects in my viewModel is updated (after a PUT request, for example).
Let me explain :
My model :
public class MyObject
{
public string Id { get; private set; }
public string Name { get; private set; }
}
My viewmodel :
public class MyViewModel : BaseViewModel
{
public MyObject MyObject { get; private set; }
public string IdMvvm
{
set
{
if (this.MyObject.Id != value)
{
MyObject.Id = value;
OnPropertyChanged(nameof(IdMvvm));
}
}
get { return MyObject.Id; }
}
public string NameMvvm
{
set
{
if (this.MyObject.Name != value)
{
MyObject.Name = value;
OnPropertyChanged(nameof(NameMvvm));
}
}
get { return MyObject.Name; }
}
}
BaseViewModel implements INotifyPropertyChanged
public class BaseViewModel : INotifyPropertyChanged
{
public string PageTitle { get; protected set; }
LayoutViewModel() {}
// MVVM ----------------------------------------------------------------------------------------
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected void SetValue<T>(ref T backingField, T value, [CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(backingField, value))
return;
backingField = value;
OnPropertyChanged(propertyName);
}
MyViewModel is defined as BindingContext for my page
My properties IdMvvm and NameMvvm are bind in Entry in my page in xaml
When I modify an Entry then the value is raised but if my MyModel object changes value, for example update (click on a button) then the value of the different Entry is not updated
Can you help me please? Because it seems that I missed something ...
If you need more explanation, tell me to know
Sorry if my english is not good
It is because when you change the model, your view is not aware about the change. Update your code so that you explicitly notify property changes when your model changes.
public class MyViewModel : BaseViewModel
{
private MyObject _myObject;
public MyObject MyObject
{
get { return _myObject; }
private set { _myObject = value; NotifyModelChange(); }
}
public string IdMvvm
{
set
{
if (this.MyObject.Id != value)
{
MyObject.Id = value;
OnPropertyChanged(nameof(IdMvvm));
}
}
get { return MyObject.Id; }
}
public string NameMvvm
{
set
{
if (this.MyObject.Name != value)
{
MyObject.Name = value;
OnPropertyChanged(nameof(NameMvvm));
}
}
get { return MyObject.Name; }
}
private void NotifyModelChange()
{
OnPropertyChanged(nameof(IdMvvm));
OnPropertyChanged(nameof(NameMvvm));
}
}

"Cascade" binding on ObservableCollection, containing other ObservableCollection

I have a project where I need to display a list of contract (Class Affaire).
Each contract has a list of phases (Class Phase).
I display each of them in 2 different ListView using binding.
Problem is when I remove a Phase from ListView, nor the ListView where are displayed Phases, nor my ObjectCollection are updated.
I created a context with two distinct ObservableCollection :
ObservableCollection, where is the list of Affaire.
ObservableCollection that are list of phases present in selected Affaire
My context is made as follow :
public class Contexte : INotifyPropertyChanged
{
private Affaire selectedAffaire;
private Phase selectedPhase;
private Assemblage selectedAssemblage;
public Affaire SelectedAffaire
{
get { return selectedAffaire; }
set
{
selectedAffaire = value;
this.NotifyPropertyChanged("SelectedAffaire");
}
}
public Phase SelectedPhase
{
get { return selectedPhase; }
set
{
selectedPhase = value;
this.NotifyPropertyChanged("SelectedPhase");
}
}
public Assemblage SelectedAssemblage
{
get { return selectedAssemblage; }
set
{
selectedAssemblage = value;
this.NotifyPropertyChanged("SelectedAssemblage");
}
}
private ObservableCollection<Affaire> listeDesAffaires;
public ObservableCollection<Affaire> ListeDesAffaires
{
get { return listeDesAffaires; }
set { NotifyPropertyChanged(ref listeDesAffaires, value); }
}
/**************************************************/
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string nomPropriete)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(nomPropriete));
}
private bool NotifyPropertyChanged<T>(ref T variable, T valeur, [CallerMemberName] string nomPropriete = null)
{
if (object.Equals(variable, valeur)) return false;
variable = valeur;
NotifyPropertyChanged(nomPropriete);
return true;
}
}
My Class Affaire :
public class Affaire : INotifyPropertyChanged
{
public long ID { get; set; }
private string nom;
public string Nom
{
get { return this.nom; }
set
{
if (this.nom != value)
{
this.nom = value;
this.NotifyPropertyChanged("Nom");
}
}
}
private string code;
public string Code
{
get { return this.code; }
set
{
if (this.code != value)
{
this.code = value;
this.NotifyPropertyChanged("Code");
}
}
}
private string comm;
public string Comm
{
get { return this.comm; }
set
{
if (this.comm != value)
{
this.comm = value;
this.NotifyPropertyChanged("Comm");
}
}
}
private ObservableCollection<Phase> listPhases;
public ObservableCollection<Phase> ListPhases {
get { return listPhases; }
set
{
listPhases = value;
if (PropertyChanged != null)
{
NotifyPropertyChanged("ListPhases");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
....
}
My class Phase :
public class Phase : INotifyPropertyChanged
{
private string nomPhase;
public string NomPhase
{
get { return this.nomPhase; }
set
{
if (this.nomPhase != value)
{
this.nomPhase = value;
this.NotifyPropertyChanged("NomPhase");
}
}
}
private int priorite;
public int Priorite
{
get { return this.priorite; }
set
{
if (this.priorite != value)
{
this.priorite = value;
this.NotifyPropertyChanged("Priorite");
}
}
}
private string commPhase;
public string CommPhase
{
get { return this.commPhase; }
set
{
if (this.commPhase != value)
{
this.commPhase = value;
this.NotifyPropertyChanged("CommPhase");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
public long IdAffaire { get; set; }
public long ID { get; set; }
private ObservableCollection<Assemblage> listAssemblages;
public ObservableCollection<Assemblage> ListAssemblages
{
get { return listAssemblages; }
set
{
listAssemblages = value;
if (PropertyChanged != null)
{
NotifyPropertyChanged("ListAssemblages");
}
}
}
...
}
1) When I doubleclick on a contract(in ListView1), I display in ListView2 list of its phases, I do the following :
contexte.SelectedAffaire = (Affaire)ListView1.SelectedItem;
contexte.SelectedAffaire.getListPhases();
afficherListview("2");
2) When I edit my Phase, all is updated correctly in my view, and also in my ObservableCollection
3) For adding/removing a new Phase, all is solved.
Edit :
Example given by Netstep works perfectly but I still meet an issue :
I have a third level "Assembly", this is an ObservableCollection in class "Phase", I have no problem to navigate with the four ListViews, but I meet a problem when I want to make something else : When I right-click on the header of "Phase", I want to display in the list of Assembly, the list of all assemblies contained in Affaire, without filtering on Phase.
For this I do the following : I am on the 3rd level listview Assemblies, I make right click on Phase header and event is as following :
Phase ph = new Phase();
ph.IdAffaire = contexte.SelectedAffaire.ID;
ph.ListAssemblages = new ObservableCollection<Assemblage>(contexte.SelectedAffaire.getListAssemblages(true));
contexte.SelectedPhase = ph;
I "shit" a bit making a new empty phase, just to put an ObservableCollection inside and bind the ObservableCollection to my ListView3.
Edit : That part of code works good... I just refreshed the context somewhere in my code and forgot about it, sure that there was something wrong in biding... All solved thanks
Here is the example, based on your source, that will handle all stuff.
a View Models:
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace WpfApp2
{
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string nomPropriete)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(nomPropriete));
}
}
public class Contexte : BaseViewModel
{
private Affaire _selectedAffaire;
private Phase _selectedPhase;
public ObservableCollection<Affaire> ListeDesAffaires { get; set; }
public Affaire SelectedAffaire
{
get { return _selectedAffaire; }
set
{
_selectedAffaire = value;
this.NotifyPropertyChanged("SelectedAffaire");
}
}
public Phase SelectedPhase
{
get { return _selectedPhase; }
set
{
_selectedPhase = value;
this.NotifyPropertyChanged("SelectedPhase");
}
}
public Contexte()
{
ListeDesAffaires = new ObservableCollection<Affaire>
{
new Affaire("Affaire1"),
new Affaire("Affaire2")
};
}
}
public class Affaire : BaseViewModel
{
private string nom;
public string Nom
{
get { return this.nom; }
set
{
this.nom = value;
this.NotifyPropertyChanged("Nom");
}
}
public ObservableCollection<Phase> ListPhases { get; set; }
public Affaire(string n)
{
nom = n;
ListPhases = new ObservableCollection<Phase>
{
new Phase { NomPhase = nom + "_Phase1" },
new Phase { NomPhase = nom + "_Phase2" }
};
}
}
public class Phase : BaseViewModel
{
private string nomPhase;
public string NomPhase
{
get { return this.nomPhase; }
set
{
this.nomPhase = value;
this.NotifyPropertyChanged("NomPhase");
}
}
public ObservableCollection<Assemblage> ListAssemblages { get; set; }
}
public class Assemblage : BaseViewModel
{
private string nom;
public string Nom
{
get { return this.nom; }
set
{
this.nom = value;
this.NotifyPropertyChanged("Nom");
}
}
}
}
a MainWindow.xaml:
<Window x:Class="WpfApp2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:Contexte x:Name="Contexte" d:IsDataSource="True" />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding ListeDesAffaires}" DisplayMemberPath="Nom" SelectedItem="{Binding SelectedAffaire}"/>
<ListBox Grid.Column="1" ItemsSource="{Binding SelectedAffaire.ListPhases}" DisplayMemberPath="NomPhase" />
<Button Grid.Column="2" VerticalAlignment="Top" Click="FillClick">Fill</Button>
<ListBox Grid.Column="2" ItemsSource="{Binding SelectedPhase.ListAssemblages}" DisplayMemberPath="Nom" Margin="0,20,0,0"/>
</Grid>
</Window>
And some code from your question (MainWindow.xaml.cs):
using System.Collections.ObjectModel;
using System.Windows;
namespace WpfApp2
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void FillClick(object sender, RoutedEventArgs e)
{
Phase ph = new Phase();
ph.NomPhase = "SomeId";
ph.ListAssemblages = new ObservableCollection<Assemblage>()
{
new Assemblage { Nom = "Assemblage1" },
new Assemblage { Nom = "Assemblage2" }
};
Contexte.SelectedPhase = ph;
}
}
}
And here is the result:
This is basic sample that you can extend. It handles all field modification and Add/Remove objects and displays on screen. There is no additional code in MainWindow.xaml.cs. Please ask questions, if any.

mvvm selected listview items to list<string> in object

I have a MVVM program with a model:
public class Deelnemer
{
public int Id { get; set; }
public string Voornaam { get; set; }
public string Werkplek { get; set; }
public List<string> Aanwezig { get; set; }
public Deelnemer()
{
}
}
In my View I have a listBox in which I want to be able to select multiple values (days to put in the list aanwezig).
<ListBox Name="listDagdelen" SelectionMode="Multiple" ItemsSource="{Binding Dagdelen}" SelectedItem="{Binding SelectedDagdeel, Mode=TwoWay}">
The ViewModel looks as follows:
class DeelnemerViewModel : INotifyPropertyChanged
{
#region Private Variables
private readonly Deelnemer dlnObject;
private readonly ObservableCollection<Deelnemer> deelnemers;
private readonly DeelnemerManager deelnemerManager;
private readonly ICommand addDeelnemerCmd;
private readonly ICommand deleteDeelnemerCmd;
#endregion
public ObservableCollection<string> Dagdelen { get; private set; }
#region constructor
public DeelnemerViewModel()
{
Dagdelen = new ObservableCollection<string>() { "maandagochtend", "maandagmiddag", "dinsdagochtend", "dinsdagmiddag", "woensdagochtend", "woensdagmiddag", "donderdagochtend", "donderdagmiddag", "vrijdagochtend", "vrijdagmiddag" };
dlnObject = new Deelnemer();
deelnemerManager = new DeelnemerManager();
deelnemers = new ObservableCollection<Deelnemer>();
addDeelnemerCmd = new RelayCommand(Add, CanAdd);
deleteDeelnemerCmd = new RelayCommand(Delete, CanDelete);
}
#endregion
#region Properties
private string _selectedDagdeel = null;
public string SelectedDagdeel
{
get { return _selectedDagdeel; }
set
{
_selectedDagdeel = value;
dlnObject.Aanwezig.Add(value);
OnPropertyChanged("SelectedDagdeel");
}
}
public int Id
{
get { return dlnObject.Id; }
set
{
dlnObject.Id = value;
OnPropertyChanged("Id");
}
}
public string Voornaam
{
get { return dlnObject.Voornaam; }
set
{
dlnObject.Voornaam = value;
OnPropertyChanged("Voornaam");
}
}
public string Werkplek
{
get { return dlnObject.Werkplek; }
set
{
dlnObject.Werkplek = value;
OnPropertyChanged("Werkplek");
}
}
public List<string> Aanwezig
{
get { return dlnObject.Aanwezig; }
set
{
dlnObject.Aanwezig = value;
OnPropertyChanged("Aanwezig");
}
}
public ObservableCollection<Deelnemer> Deelnemers { get { return deelnemers; } }
public Deelnemer SelectedDeelnemer
{
set
{
Id = value.Id;
Voornaam = value.Voornaam;
Werkplek = value.Werkplek;
Aanwezig = value.Aanwezig;
}
}
#endregion
#region Commands
public ICommand AddDeelnemerCmd { get { return addDeelnemerCmd; } }
public ICommand DeleteDeelnemerCmd { get { return deleteDeelnemerCmd; } }
#endregion
public bool CanAdd(object obj)
{
//Enable the Button only if the mandatory fields are filled
if (Voornaam != string.Empty && Werkplek != string.Empty)
return true;
return false;
}
public void Add(object obj)
{
var deelnemer = new Deelnemer { Voornaam = Voornaam, Werkplek = Werkplek, Aanwezig = Aanwezig };
if (deelnemerManager.Add(deelnemer))
{
Deelnemers.Add(deelnemer);
//string txt = string.Join(String.Empty,Aanwezig);
//MessageBox.Show(txt);
//ResetDeelnemer();
}
else
MessageBox.Show("Vul correcte waardes in!");
}
#region DeleteCommand
private bool CanDelete(object obj)
{
//Enable the Button only if the patients exist
if (Deelnemers.Count > 0)
return true;
return false;
}
private void Delete(object obj)
{
//Delete patient will be successfull only if the patient with this ID exists.
if (!deelnemerManager.Remove(Id))
MessageBox.Show("Deelnemer met dit id bestaat niet!");
else
{
//Remove the patient from our collection as well.
deelnemers.RemoveAt(GetIndex(Id));
ResetDeelnemer();
MessageBox.Show("Deelnemer succesvol verwijderd !");
}
}
#endregion
#region Private Methods
private void ResetDeelnemer()
{
Id = 0;
Voornaam = string.Empty;
Werkplek = string.Empty;
Aanwezig.Clear();
}
private int GetIndex(int Id)
{
for (int i = 0; i < Deelnemers.Count; i++)
if (Deelnemers[i].Id == Id)
return i;
return -1;
}
#endregion
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
I can't figure out how I should use the List with the listbox values. How do I add (multiple) listbox values to the object's List?
The current code throws a nullreferenceexception at
dlnObject.Aanwezig.Add(value);
You must initialize the Aanwezig property of the Deelnemer object before you can add any values to it, either in the contructor of DeelnemerViewModel:
dlnObject = new Deelnemer();
dlnObject.Aanwezig = new List<string();
...or in the constructor of the Deeelnemer class:
public Deelnemer()
{
Aanwezig = new List<string();
}

Add new Item to the listbox from other window

In my wpf application, I've created two view classes, DayView and CustomView. In DayView, there is a listbox consist of some entries. In listbox, there is stackpanel with 5 textboxes. In my CustomView class, also I've created stackpanel with 5 textboxes. when I enter data into those textboxes of CustomView and click on save button,the new entry should create and data should saved in respective textboxes of DayView.
CustomView class:
namespace TimeSheet
{
/// <summary>
/// Interaction logic for CustomView.xaml
/// </summary>
public partial class CustomView : Window
{
public List<Harvest_Project> projectList { get; set; }
public List<Harvest_Client> clientList { get; set; }
public Harvest_Project selectedProjectid { get; set; }
public Harvest_Client selectedClientid { get; set; }
private string client { get { return ClientText.Text; } set { ClientText.Text=value;} }
private string application { get { return ApplicationText.Text; } set { ApplicationText.Text = value; } }
private string starttime { get { return StartTimeText.Text; } set { StartTimeText.Text = value; } }
private string stoptime { get { return StopTimeText.Text; } set { StopTimeText.Text = value; } }
private string task { get { return TaskText.Text; } set { TaskText.Text = value; } }
private string project { get { return ProjectText.Text; } set { ProjectText.Text = value; } }
public CustomView()
{
InitializeComponent();
this.DataContext = this;
Globals._globalController.setCustomViewWindow(this);
clientList = Globals._globalController.harvestManager._CLIENTLIST;
projectList = Globals._globalController.harvestManager._PROJECTLIST;
}
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
if (sender is Harvest_TimeSheetEntry)
{
//Harvest_TimeSheetEntry entry = new Harvest_TimeSheetEntry();
//if (!entry.isSynced)
//{
// entry.ClientNameBinding = client;
// entry.ApplicationNameBinding = application;
// entry.StartTimeBinding = starttime;
// entry.StopTimeBinding = stoptime;
// entry.TaskNameBinding = task;
// entry.ProjectNameBinding = project;
//}
Globals._globalController.getDayViewWindow.Show();
this.Hide();
}
}
private void ClientComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
string text = (sender as ComboBox).SelectedItem.ToString();
}
private void ProjectComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
string text = (sender as ComboBox).SelectedItem.ToString();
}
}
}
I don't understand, how should i save this data in DayView listbox. Please suggest some ways.!
This is DayView window
[1]: http://i.stack.imgur.com/1Qi0e.png
This is CustomView window!
[2]: http://i.stack.imgur.com/mACxR.png
In my opinion it's more suitable to use an mvvm Framework to make your solution more structured, and then use a Messenger to make communication between your views.

Categories

Resources