How to trap the event when a child is been added, how can a child object has access to a property of his parent

How to trap the event when a child is been added, how can a child object has access to a property of his parent

Old forum URL: forums.lhotka.net/forums/t/5433.aspx


alef posted on Friday, September 19, 2008

I’ve the following classes for a Point Of Sale application:

Model : EditableRoot

àModelColors : EditableChildList

   àModelColor : EditableChild

       à Articles : EditableChildList

            à Article : EditableChild

 

BeamOfMeasures : NameValueListBase

SizeList : NameValueListBase

 

I want to implement the following use case:

User fills in a new model (with properties like Season, Mark, Beam of measures)

User add colors in which the model can be delivered.

When a new color is been added (ModelColor), automatically records must be added to the Articles collection of this ModelColor instance. For each article instance the properties ModelColorId and SizeId must be filled in automatically by the business layer. So the number of records of the Articles collection corresponds to the number of existing sizes for the chosen “Beam of Measures”.

User fills in the sell price for the different sizes for the different colors.

 

So when the user chooses a different “Beam of Measures”, or adds a color, the sizes must be automatically displayed

         e.g. a grid with all the possible sizes on the first column and the second column the price of the article.

Size                  Price

       36  

37  

38   

39                    

40                    

41   

42

 

 

I’ve already the following code in the class Model for the property BeamOfMeasuresLID.

This solves the problem when the user is changing the property “Beam Of Measures” of the Model.

 

public int BeamOfMeasuresLID

{

  get

  {

     CanReadProperty("BeamOfMeasuresLID", true);

     return _beamOfMeasuresLID;

  }

  set

  {

     CanWriteProperty("BeamOfMeasuresLID", true);

     if (!_beamOfMeasuresLID.Equals(value))

     {

       _beamOfMeasuresLID = value;

       PropertyHasChanged("BeamOfMeasuresLID");

      SizeList SizeList = SizeList.GetSizeListByBeamOfMeasuresLID(_beamOfMeasuresLID);

      foreach (ModelColor tmpModelKleur in this.Colors)

      {

        tmpModelColor.Articles.Clear();

       

        foreach (SizeList.NameValuePair item in SizeList)

        {

          Article tmpArticle = tmpModelColor.Articles.AddNew();

          tmpArticle.ModelKleurId = tmpModelColor.Id;

          tmpArticle.SizeId = item.Key;

          tmpArticle.Size = item.Value;

        }

       

      }

     }

  }

}

 

But I don’t know how to trap the event when the user has added a color, to let also automatically appear the sizes. So the other colors which are already been added must not be touched, but for the new color the different sizes must appear so the user can fill in the sell price. So the things I don’t know how to do are how to trap when a color is added and how can I know what is the value of the property “Beam Of Measures” of the parent Model, because children doesn’t know anything about their parent.

 

alef replied on Tuesday, September 23, 2008

The code I posted already is not so good. I've changed it to the following by keeping in mind the separation of concerns rule. The code in the class Model will delegate the creation of the articles to his child collection ModelColors, which in turn will delegate it to the child object ModelColor.
I've found also how I can trap the event when a child object ModelColor is been added.
The only thing which I can't find is how I can get access to a parent property?


1) class Model

public int BeamOfMeasuresLID

{

  get

  {

     CanReadProperty("BeamOfMeasuresLID", true);

     return _beamOfMeasuresLID;

  }

  set

  {

     CanWriteProperty("BeamOfMeasuresLID", true);

     if (!_beamOfMeasuresLID.Equals(value))

     {

       _beamOfMeasuresLID = value;

       PropertyHasChanged("BeamOfMeasuresLID");

       Colors.CreateAvailableArticles(_beamOfMeasuresLID);  

     }

  }

}

2) class ModelColors

    public void
CreateAvailableArticles(int beamOfMeasuresLID)
    {
      foreach (ModelColor child in this)
      {
        child.
CreateAvailableArticles(beamOfMeasuresLID));
      }
    }

    protected override void OnListChanged(System.ComponentModel.ListChangedEventArgs e)
    {
       if (e.ListChangedType == ListChangedType.ItemAdded)
       {
              this[e.NewIndex].
CreateAvailableArticles(  ?????  );

=====> here I don't know what to do because I don't have access to the property
BeamOfMeasuresLID of the parent object Model

       }
       base.OnListChanged(e);
    }

3) class ModelColor

    public void
CreateAvailableArticles((int beamOfMeasuresLID)
    {
     
SizeList sizeList = SizeList.GetSizeListByBeamOfMeasuresLID(_beamOfMeasuresLID);
      Articles.Clear();
      foreach (SizeList.NameValuePair item in sizeList)
      {
        Article tmpArticle =
Articles.AddNew();
       
tmpArticle .ModelColorId = Id;
       
tmpArticle .SizeId = item.Key;
       
tmpArticle .Size = item.Value;
      }
    }



Fintanv replied on Tuesday, September 23, 2008

 If your child collection always exists as a child of your root BO, then I do not see a problem doing the following:

     
protected override void OnListChanged(System.ComponentModel.ListChangedEventArgs e)
{
    if (e.ListChangedType == ListChangedType.ItemAdded)
    {
        if (this.Parent != null)
        {
            int id = ((Model)this.Parent).BeamOfMeasuresLID;  // borrow the property from the root parent object
            this[e.NewIndex].CreateAvailableArticles(id);

        }
    }
    base.OnListChanged(e);
}


alef replied on Tuesday, September 23, 2008

Thank you for the reply.

But Parent is not a recognized property. I get the following error
ShoeSoft.Library.ModelColors' does not contain a definition for 'Parent'

I'm using version 3.0.4 of the CSLA framework.
Did you implement yourself this property Parent?
If so can you provide a piece of code?

alef replied on Wednesday, September 24, 2008

The class ModelColors is a BusinessListBase and this does not contain a variable to hold a reference to the parent.

Fintanv replied on Wednesday, September 24, 2008

I used this with CSLA 3.5.x where it is provided.  However in the past I have added this to my collection class through custom code.  Just add a variable to hold the parent reference and mark it with the NotUndoable attribute.  You will then need to use some mechanism to set the parent when your child is created and / or deserialized.  If you take a look at the 3.5 code you should be able to see what Rocky added.

Best of luck.

alef replied on Friday, October 24, 2008

I've migrated the project to version 3.5.2.

I removed the old csla.dll and put a reference to the new csla.dll.

I didn't need to change anything else. It worked immediately. Thanks Lhotka for the backwards compatibility.

Now I have the property parent in the version 3.5.2

int id = ((Model)this.Parent).BeamOfMeasuresLID;  // borrow the property from the root parent object

but this.Parent contains null.

Do I need to change something at the business layer before this will work?

 

Copyright (c) Marimer LLC