Reputation: 77
I'm stuck on following:
I have an application gui as follows:
I created a seperate class library for 'klant' which contains a string 'Naam' and an integer 'Consumpties'and linked this to my project.
When the user adds a name (Naam) and a number of consumptions (Consumpties), these values are addes to a listbox.
Here is my code so far:
private void btnKlantToevoegen_Click(object sender, RoutedEventArgs e)
{
List<Klant> klanten = new List<Klant>();
klanten.Add(new Klant
{
Naam = txtKlantNaam.Text,
Consumpties = int.Parse(txtKlantConsumpties.Text)
}
);
for (int i = 0; i < klanten.Count; i++)
{
lbOverzicht.Items.Add(klanten[i]);
}
I need to calculate the sum of the entered clients and consumptions, but i'm stuck on how to properly achieve this.
Also, there needs to be set a maximum number of consumptions per client and a maximum of total consumptions.
How to call this?
I tried creating a method to calculate the total of consumptions, but am not able to accomplish results. The code i have for this so far is as follows:
int BerekenTotaalConsumpties(int totaalconsumpties)
{
totaalconsumpties = 0;
int consumpties = int.Parse(txtKlantConsumpties.Text);
for (int i = 0; i <= consumpties; i++)
{
totaalconsumpties += Convert.ToInt32(lbOverzicht.Items[i].ToString());
}
return totaalconsumpties;
}
The result of this method then needs to be places in a label. I would do this as follows:
lblOverzicht.Content = BerekenTotaalConsumpties();
Klant class as follows:
public class Klant
{
public string Naam;
public int Consumpties;
public override string ToString()
{
return string.Format("{0} ({1})", this.Naam, this.Consumpties);
}
}
How can the names (Naam) be sorted alphabetically? Untill now we have
lbOverzicht.Items.SortDescriptions.Add(new SortDescription("", ListSortDirection.Ascending));
But this doens't seem to work?
How can we verify that the users enters letters in field Naam and numbers in field Consumptions?
Upvotes: 1
Views: 903
Reputation: 495
For the counting, try this:
int totalNaams = 0;
int totalConsumpties = 0;
foreach (Klant item in klanten)
{
totalConsumpties += item.Consumpties;
totalNaams += 0;
}
As for limiting the number of Consumpties per client, that needs to be done before you add it to the listbox. Just check to see if it's less than or equal to your max.
For limiting the total Comsumpties, You will need to calculate the new total after each new addition to the ListView. That would probably require a different approach to the counting so you're not executing the foreach more times that you need to.
<ListView x:Name="lbOverzicht" HorizontalAlignment="Left" Height="200" Margin="435,372,0,0" VerticalAlignment="Top" Width="177">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Naam}" />
<GridViewColumn DisplayMemberBinding="{Binding Consumpties}" />
</GridView>
</ListView.View>
</ListView>
int totalNaams = 0;
int totalConsumpties = 0;
int consumptiesTotalMax = 0;
int consumptiesMax = 0;
List<Klant> klanten = new List<Klant>();
public class Klant
{
public string Naam { get; set; }
public int Consumpties { get; set; }
public override string ToString()
{
return string.Format("{0} ({1})", this.Naam, this.Consumpties);
}
}
public void btnKlantToevoegen_Click(object sender, RoutedEventArgs e)
{
int current = int.Parse(txtKlantConsumpties.Text);
consumptiesTotalMax = int.Parse(txtTotalMax.Text);
consumptiesMax = int.Parse(txtConsumpMax.Text);
if (!string.IsNullOrEmpty(txtKlantConsumpties.Text.Trim()) && !string.IsNullOrEmpty(txtKlantNaam.Text.Trim()))
{
if (((totalConsumpties + current) <= consumptiesTotalMax) && (current <= consumptiesMax))
{
klanten.Add(new Klant
{
Naam = txtKlantNaam.Text,
Consumpties = current
}
);
lbOverzicht.ItemsSource = klanten;
totalConsumpties += current;
totalNaams += 1;
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lbOverzicht.ItemsSource);
view.SortDescriptions.Add(new SortDescription("Naam", ListSortDirection.Ascending));
}
}
}
Upvotes: 1
Reputation: 31721
Use the power of MVVM
and the CollectionChange
event of an ObservableCollection
to handle the summing of any and all changes to that collection.
In your view model (which adheres to INotifyPropertyChange
) declare these properties
// Zehn Kleine Jagermeister!
public ObservableCollection<Klant> Overzicht
{
get { return _Overzicht; }
set { _Overzicht = value; OnPropertyChanged(); }
}
public int AantalKlanten { get { return Overzicht?.Count ?? 0; } }
public int AantalConsumpties { get; set; }
So we have the list of Klant
s and the totals. Then in the constructor of the viewmodel we allocate the observable collection and subscribe to the change of collection event:
Overzicht = new ObservableCollection<Klant>();
Overzicht.CollectionChanged += (o, args) =>
{
AantalConsumpties = Overzicht.Sum(klnt => klnt.Consumpties);
OnPropertyChanged("AantalConsumpties");
OnPropertyChanged("AantalKlanten");
};
So whenever we add or remove something from the collection, we recalculate the totals. By directly calling the OnPropertyChanged
methods for the totals we announce to the XAML controls which have bound to those properties, that the values have changed and to update them for the user to see.
Here is the binding in XAML
<ListBox ItemsSource="{Binding Overzicht}"/>
<TextBlock Text="{Binding AantalKlanten }"/>
<TextBlock Text="{Binding AantalConsumpties}"/>
Then to limit things on add of the button click, simply check AantalKlanten
and AantalCompties
before allowing an insertion (Add
) into the Overzicht collection.
The below shows the add in a button click with a max of 100. You can change it as needed.
if ((myViewModel.AantalConsumpties + newvalue) < 100)
myViewModel.Overzicht.Add(new Klant() { Naam = ..., Consumpties = newvalue});
This is the Klant
public class Klant
{
public string Naam { get; set; }
public int Consumpties { get; set; }
}
New to MVVM? Check out my quick example here Xaml: ViewModel Main Page Instantiation and Loading Strategy for Easier Binding for more information.
Upvotes: 1
Reputation: 621
public int NumConsumptionsPerClient(string client)
{
var aux = listBox1.Items;
List<int> consumptions = new List<int>();
foreach (var i in aux)
{
if (i.ToString().Contains(client))
{
consumptions.Add(Convert.ToInt32(Regex.Match(i.ToString(), @"\d+").Value)); // only gets numbers
}
}
int sumconsumptions = 0;
foreach (int k in consumptions)
{
sumconsumptions = sumconsumptions + k;
}
return sumconsumptions;
}
public int NumConsumptions()
{
var aux = listBox1.Items;
List<int> consumptions = new List<int>();
foreach (var i in aux)
{
consumptions.Add(Convert.ToInt32(Regex.Match(i.ToString(), @"\d+").Value)); // only gets numbers
}
int sumconsumptions = 0;
foreach (int k in consumptions)
{
sumconsumptions = sumconsumptions + k;
}
return sumconsumptions;
}
public int NumClients()
{
return listBox1.Items.Count;
}
With first method you can control the max. consumptions per client. (you modify the method for your object instead of string)
Second and third methods are easy to understand.
Upvotes: 0