How to represent Collection PLUS Integer in a Stack? - winforms

We are using a Stack to provide the user with a simple "back one" button. We push collections onto the stack and pop them off again when he hits back one.
Today we want to extend this a little bit. When we push a collection onto the stack we want to store an integer alongside the collection. Then when we peek at the stack we want to retrieve the collection PLUS its integer.
What's the best way to push our collection PLUS THE INTEGER onto the stack?
Should we define a Struct or Class for collection plus integer? Or some other way?

You don' t need to create a new class for this purpose. You can simply add your values into the stack like this;
stack.Push(new KeyValuePair<int, Collection>(yourInteger, yourCollection));
and get them like this;
KeyValuePair<int, Collection> valueYouWant = stack.Pop();
valueYouWant.Key --> Your integer
valueYouWant.Value --> Your collection

The simplest and out-of-the-box solution would be to extend your current container with the integer:
public class StackElement : CustomerCollection
{
public int Version {get; set;}
}
or make a composition with an integer:
public class StackElement
{
public CustomerCollection Customers {get; set;}
public int Version {get; set;}
}
and then use it just as you would use any other thing with a stack:
Stack<StackElement> stack = new Stack<StackElement>();
stack.Push(...)
var stackElement = stack.Pop();

Related

Fill a combobox in WPF with a list of web services

I have a control like this:
<ComboBox x:Name="ComboTipo"
Height="23"
SelectionChanged="ComboTipo_SelectionChanged"
Width="450"
Canvas.Left="609"
Canvas.Top="26" />
And my code is:
ComboTipo.DisplayMemberPath = "Descripcion";
ComboTipo.SelectedValuePath = "IdTipoPersona";
ComboTipo.ItemsSource = myWebServices.dameTipos();
My web services returns a list for this object, this class is created in automatic when i add the reference to the web services:
public partial class TipoPersona {
private short idTipoPersonaField;
private string descripcionField;
/// <comentarios/>
public short IdTipoPersona {
get {
return this.idTipoPersonaField;
}
set {
this.idTipoPersonaField = value;
}
}
/// <comentarios/>
public string Descripcion {
get {
return this.descripcionField;
}
set {
this.descripcionField = value;
}
}
}
But the problem is:
The combobox displays the data types for each element of the list, and i want display the Descripcion.
Can you help me plis! Thanks
What does IdTipoPersona look like? Is it a class you created? If so, you may need to reference the property that you want displayed. It would look something like this:
ComboTipoPersona.SelectedValuePath = "IdTipoPersona.Text";
Where Text would be replaced by the property. It is really hard to judge otherwise what is going on with knowing a little more about the object structure that myWebServices.dameTipos() returns.
EDIT
Ok I was able to simulate your problem and simulate a solution as well.
Your issue is in the Tipos class. There are a couple of things necessary when binding to a combobox with a custom class.
First off, you will want to add accessors and mutators (getters and setters) to IdTippoPersona and Descripcion.
You should add a constructor that assigns to those properties with parameters.
It is usually a good idea to add a default constructor.
The finished code will look like this:
public class Tipos
{
public int IdTipoPersona { get; set; }
public string Descripcion { get; set; }
public Tipos(int id, string descripcion)
{
IdTipoPersona = id;
Descripcion = descripcion;
}
}
I found the asnwer if someone needs it.
We need create a class intermediate class but we were working with entity framework, for this way, we need add the intermediate class like complex type in my model (entity framework).
And also we need override this class.
And it works so well.
Thanks for all #Goody

Binding to an array of structs in WPF

In my application I store an array of structs containing how much bills/coins i need to pay to a client and how many I effectively pay.
public struct MoneyType
{ //contains more, but left out for readability
public int Requested { get; set; } // How many are requested for a payment
public int Paid { get; set; } //bills paid to the customer
}
I made an array with these which I make accessible to the viewmodel in the following way:
MoneyType[] money; //correctly initialised in the constructor
public MoneyType[] GetMoney()
{
return money;
}
In the viewmodel itself I make these accessible in this way:
public MoneyType[] MoneyTypes //Denominations
{
get
{
return _dataService.GetMoney();
}
}
Finally, in my XAML, I accessed these as:
<cbtn:BillCounter x:Name="euro200" Value = "{Binding MoneyTypes[2].Paid, Mode=TwoWay }" />
The [2] is used to indicate which type of bills/coins I want to use.
I want to make this work 2 ways, so that my custom control can update the amount of coins/bills paid. For which I would need a setter for my MoneyTypes property.
I'm not sure the right way to do this. I have a feeling that somehow, I should not pass the entire array from my viewmodel/model, but a specific part of one of my MoneyTypes (the paid/requested fields, with some kind of index indicating which entry to use)
I'm unsure of how to do this.
May this answer is helps you - https://stackoverflow.com/a/7714924/3207043
Based on this, you need to use reference data types to bindings.

c# returning arrays via properties

Id like to firstly apologise for what may appear to be a stupid question but im confused regarding the following.
Im writting a class library which will not be running on the UI thread. Inside the CL i need an array which im going populate with data received from a stored procedure call. I then need to pass this data back to the UI thread via an event.
Originally i was going to write the following.
public class ColumnInformation
{
public string[] columnHeaderNames;
public string[] columnDataTypes;
}
but im pretty sure that would be frowned upon and i instead should be using properties.
public class ColumnInformation
{
public string[] columnHeaderNames {get; set;}
public string[] columnDataTypes {get; set;}
}
but then i came across the following.
MSDN
so am i correct in assuming that i should actually declare this as follows:
public class ColumnInformation
{
private string[] _columnHeaderNames;
public Names(string[] headerNames)
{
_columnHeaderNames = headerNames;
}
public string[] GetNames()
{
// Need to return a clone of the array so that consumers
// of this library cannot change its contents
return (string[])_columnHeaderNames.Clone();
}
}
Thanks for your time.
If your concern is the guideline CA1819: Properties should not return arrays,
It will be same whether you are exposing Array as a Public Field, or Property (making readonly does not matter here). Once your original Array is exposed, its content can be modified.
To avoid this, as the link suggest, make Field private, and return Clone from the Getter.
However major concern is that there may be multiple copies of your array if retrieved many times. It is not good for performance and synchronization.
Better solution is ReadOnlyCollection.
Using ReadOnlyCollection, you can expose the collection as read only which cannot be modified. Also any changes to underlying collection will be reflected.

Create my own API

I use in my force.com application Apex Classes, and many of them have the same structure, I want to make an API to reuse it after.
For exaple, these are two classes :
//first class
public class insererActAct{
public List<Activites_actuelles__c> accts {get; set;}
public insererActAct(ApexPages.StandardController controller){
accts = new List<Activites_actuelles__c>();
accts.add(new Activites_actuelles__c());
}
public void addrow(){
accts.add(new Activites_actuelles__c());
}
public PageReference deleteRow(){
if (accts.size()>1)
{
accts.remove(accts.size()-1);
}
return null;
}
public PageReference save()
{
insert accts;
Assure__c theParent = new Assure__c(id=accts[0].Activites_actuelles__c);
PageReference acctPage = new ApexPages.StandardController(theParent).view();
acctPage.setRedirect(true);
return acctPage;
}
}
//second class
public class insererEnfants{
public List<Enfants__c> accts {get; set;}
public insererEnfants(ApexPages.StandardController controller){
accts = new List<Enfants__c>();
accts.add(new Enfants__c());
}
public void addrow(){
accts.add(new Enfants__c());
}
public PageReference deleteRow(){
if (accts.size()>1)
{
accts.remove(accts.size()-1);
}
return null;
}
public PageReference save()
{
insert accts;
Assure__c theParent = new Assure__c(id=accts[0].Parent__c);
PageReference acctPage = new ApexPages.StandardController(theParent).view();
acctPage.setRedirect(true);
return acctPage;
}
}
Can any one tell me it is possible or not, if yes, how can I do this, please ?
Do you mean you want to write code that works for different kinds of objects, rather than stating the type of object in the code?
It is possible to do this, by declaring your sObject variables with the sObject type, e.g, instead of
public List<Activites_actuelles__c> accts {get; set;}
you would put
public List<sObject> sObjects{get; set;}
and by referencing fields using get and put, e.g. instead of
Account theAccount = new Account();
theAccount.name = 'Fred';
you would put
sObject theSObject = new SObject();
theSObject.put('name', 'Fred');
I've not tried using code like this in a controller extension, but in theory since you can pass in any standard controller you ought to be OK.
You will need to think about how to create the parent object inside the save method, because you will need to pass in what type you want to create. It's quite complicated but it is possible to take in a string representing the object type (e.g. 'Account') and create a new object of that type:
Schema.getGlobalDescribe().get('Account').newSObject()
will get you a new Account. So you could replace 'Account' with any type passed in as a parameter.
For more information look up Dynamic Apex, Dynamic SOQL and Dynamic DML in the documentation.
A word of warning: Passing around object types and field names as strings means that the compiler will not know those types are mentioned in the code. So if you try and delete a custom object or rename a field, salesforce will not warn you that the object or field is in use and will allow you to do the deletion.
Another word of warning: Although this allows code reuse and that is a benefit, you may find it is not worth it. I avoid writing dynamic apex unless I absolutely have to. It is far more complex than ordinary apex and it is therefore difficult to debug and maitain, especially if someone other than yourself has to maintain it.

makePersistent is appending elements to my list instead of replacing the list

I'm using the GAE datastore with JDO to hold course information. Each Course has a List of GradeDefinition objects (e.g. "A=90%+", "B=80%+", etc)
When I try to change the List, the new elements are simply appended behind the old elements. I suspect there is a problem with the way I am using detachable objects and persistence managers.
A basic rundown:
#PersistenceCapable(detachable = "true")
public class Course
{
#Persistent(defaultFetchGroup = "true")
private GradingPolicy gradingPolicy;
}
#PersistenceCapable(detachable = "true")
public class GradingPolicy
{
#Persistent(defaultFetchGroup = "true")
private List<GradeDefinition> gradeDefinitions;
}
#PersistenceCapable(detachable = "true")
public class GradeDefinition
{
#Persistent
private String gradeName; //e.g. "A", "B", etc.
}
Then, when I want to update the list of GradeDefinition objects in a Course, I:
Get the course object (which automatically fetches its GradingPolicy, which automatically fetches its list of GradeDefinition objects),
Prepare my new list of GradeDefinitions with
List<GradeDefinition> newDefinitions = new ArrayList<GradeDefinitions>();
newDefinitions.add(new GradeDefinition("X")); //for example
newDefinitions.add(new GradeDefinition("Y"));
Reset the list by calling course.getGradingPolicy.setGradeDefinitions(newDefinitions);
Persist the changes by calling persistenceManager.makePersistent(course);
But, if the grading policy originally had A, B, and C in it, it now holds A, B, C, X, and Y!
Is there something I need to do to clear the list? Do I need to manually delete the old GradeDefinitions?
Watch out for inconsistencies between multiple PersistanceManagers, or even better, only have a single PersistanceManager floating around at a time.

Resources