2

I have my main object Person with a collection of Adrresses value object like this:

public class Person
{
    public virtual int Id {get; set;}
    public virtual string Name {get; set;}
    private IList<Adrress > _adrresses= new List<Adrress>();
    public virtual IEnumerable Adrress Adrresses {...}

    public virtual void AddAddress(Address a){...}
    public virtual void RemoveAddress(Address a){...}
    public virtual void ChangeAddress(OldAddress oa, OldAddress oa)
    {
        int index = _adrresses.IndexOf(oa);
        if (index != -1)
            _adrresses[index] = oa;
    }
}

public class Adrress 
{
    public virtual string Street {get; set;}
    public virtual string Number {get; set;}
    public virtual string City {get; set;}
    ... other 7 fields
}

In my asp page I have a Gridview where user can add, remove or change addresses.

Question is: How can I get the correct address from one user selection in grid? Do I have to read every fields from grid and use them to construct the address that I have to search?

I use CommandArgument to pass Container.DataItemIndex so ican't use it to send entire object to code

EDIT: this is an extract of the grid:

<asp:GridView ID="gvElencoFaseAttivita" runat="server" 
    AllowPaging="false" AutoGenerateColumns="False" 
    Width="100%" CssClass="datiGridView tabletwo" ShowHeader="False" 
    OnRowCommand="gvElencoFaseAttivita_RowCommand" 
    OnRowUpdating="gvElencoFaseAttivita_RowUpdating" 
    OnRowDeleted="gvElencoFaseAttivita_RowDeleted" 
    OnRowEditing="gvElencoFaseAttivita_RowEditing" 
    OnRowCancelingEdit="gvElencoFaseAttivita_RowCancelingEdit">
    <Columns>
        <asp:TemplateField HeaderText="Sel">
            <ItemTemplate>
                <asp:LinkButton ID="lbtnEditFaseAttivita" runat="server" CausesValidation="False" CommandName="Edit" CommandArgument='<%# Container.DataItemIndex %>' ToolTip="Modifica la fase" CssClass="imgModificaPiccola" />
            </ItemTemplate>
            <EditItemTemplate>
                <asp:LinkButton ID="lbtnAggiornaFaseAttivita" runat="server" ValidationGroup="UpdateFaseAttivitaGrid" CommandName="Update" CssClass="imgSalvaPiccola" ToolTip="Salva le modifiche" CommandArgument='<%# Container.DataItemIndex %>' />
            </EditItemTemplate>
            <ItemStyle CssClass="gestioneFaseAttivitaTd2" />
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Street" SortExpression="Street">
            <ItemTemplate>
                <asp:Label ID="lblStreet" runat="server" Text='<%# ((Adrress)Container.DataItem).Street %>'></asp:Label>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="txtEditStreet" runat="server" Text='<%# ((Adrress)Container.DataItem).Street %>'></asp:TextBox>
            </EditItemTemplate>
            <ItemStyle CssClass="gestioneFaseAttivitaTd3" />
        </asp:TemplateField>
    </Columns>
    <SelectedRowStyle CssClass="selezioneGridView" />
    <AlternatingRowStyle CssClass="odd" />
</asp:GridView>

and this the dataBind

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
        loadGridAddress();
}

protected void loadGridAddress()
{
    using (iuow = kernel.Get<IUnitOfWork>())
    {
        gvElencoFaseAttivita.DataSource = person.Addresses;
        gvElencoFaseAttivita.DataBind();
    }
}

protected void gvElencoFaseAttivita_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    var a = e.OldValues[""];  //e.OldValues  here is empty
}
ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
gt.guybrush
  • 1,320
  • 3
  • 19
  • 48
  • You may find the information that you need in this post: http://stackoverflow.com/questions/36827111/asp-net-gridview-how-to-edit-and-delete-data-records/36828018#36828018. – ConnorsFan Jun 03 '16 at 14:14
  • it make use of DataKeyNames, while iam looking for a way to pass Container.DataItem. i have also problem in RowUpdating since OldValues and newValues are empty since i have no ObjectDataSource (and i load gridview only if is not postback – gt.guybrush Jun 03 '16 at 14:25
  • I would need to see the code where you bind the data to the GridView to understand how it works. And maybe the markup of the GridView also. – ConnorsFan Jun 03 '16 at 14:28
  • see now my edited question – gt.guybrush Jun 03 '16 at 14:37

1 Answers1

1

You can define a method that gives a string representation of your object, and a constructor that accepts the same representation. Since you mention JSON in a comment, it could be:

public class Address 
{
    public virtual string Street {get; set;}
    public virtual string Number {get; set;}
    public virtual string City {get; set;}
    ...

    public string ToJSON()
    { 
        // Encode the object as as JSON string
        ...
        return strJSON;
    }

    public Address(string json)
    {
        // Decode JSON string and set object properties
        ...
    }
}

You could save that JSON string in a hidden field:

<EditItemTemplate>
    <asp:HiddenField ID="hfAddress" runat="server" Value='<%# ((Address)Container.DataItem).ToJSON() %>' />
    <asp:TextBox ID="txtEditStreet" runat="server" Text='<%# ((Address)Container.DataItem).Street %>'/>
    ...
</EditItemTemplate>

And retrieve it in the RowUpdating event handler to re-create the original object:

protected void gvElencoFaseAttivita_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    GridViewRow row = gvElencoFaseAttivita.Rows[e.RowIndex];
    HiddenField hfAddress = row.FindControl("hfAddress") as HiddenField;
    TextBox txtEditStreet = row.FindControl("txtEditStreet") as TextBox;
    Address oldAddress = new Address(hfAddress.Value);
    string newStreet = txtEditStreet.Text;
    ...
}
ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
  • or directly without eval to avoid having field write as string in aspx. iam also playing with Newtonsoft.Json.JsonConvert.SerializeObject((FaseAttivita)Container.DataItem to save entire object as single string – gt.guybrush Jun 03 '16 at 15:49
  • 1
    You could define an `ObjectValue` string property of the address class, which would contain a full representation of the object, and save the value of that property in a HiddenField. – ConnorsFan Jun 03 '16 at 15:55
  • 1
    why not json? and why i can't avoid to code property name in string? now upvote your answer, if edit to avoid "magic string" i will accept it. now i have to go home and out of work till monday. for now thanks – gt.guybrush Jun 03 '16 at 15:59
  • It could be JSON, yes. I updated my answer. Sorry, I was somewhat slow to understand the way you want to access data in markup. (N.B. In my code samples, I wrote "Address" instead of "Adrress".) – ConnorsFan Jun 05 '16 at 03:23
  • 1
    done it with this modification: ic ascx and DeserializeObject in code behind – gt.guybrush Jun 15 '16 at 08:33