2011-07-24 6 views
1

グリッドビューコントロールは、複雑なオブジェクトのデータバインディングを簡単にします。私のシナリオでは、グリッドビューコントロールは、顧客オブジェクトにバインドされ、いくつかの「フラット」プロパティと、タイプアドレスのオブジェクトを取る1つの複合プロパティがあります。グリッドは、期待どおりのデータを表示します。問題は、コードの背後にあるAddressプロパティの値にアクセスする方法が見つからないことです。グリッドビューコントロールにバインドされた複雑なオブジェクトの値を取得

データバインディング::System.Data.Entity.DynamicProxies.Customer_95531162E60920A5C3C02043F6564873913B91785C856624301E8B6E89906BF6は名アドレスを持つプロパティが含まれていない例えば、DataKeyNames =「ID、Address.Id」エラーで結果にDataKeyNamesコレクションを設定。

コードの背後にあるAddress.Idフィールドの値にアクセスする適切な方法は何ですか?理想的には私のような何かをしたいと思います:

protected void CustomerDetailsObjectDataSource_Selecting(object sender, ObjectDataSourceSelectingEventArgs e) 
{ 
    if (CustomersGridView.SelectedIndex < 0) return;   

    // Retrieving the Customer's id works: 
    e.InputParameters["id"] = Convert.ToString(CustomersGridView.DataKeys[CustomersGridView.SelectedIndex].Value);   

    // Retrieving the Address id doesn work: 
    e.InputParameters["id"] = Convert.ToString(CustomersGridView.DataKeys[CustomersGridView.SelectedIndex].Values["Address.Id"].ToString());   
} 

は、ここでASPコードです:

<ContentTemplate> 

     <asp:GridView ID="CustomersGridView" runat="server" AutoGenerateColumns="False" DataSourceID="CustomersObjectDataSource" 
         onselectedindexchanged="CustomersGridView_SelectedIndexChanged" DataKeyNames="Id,Address.Id" ondatabound="CustomersGridView_DataBound"> 
      <Columns> 
       <asp:TemplateField HeaderText="Aktion"> 
        <ItemTemplate> 
         <asp:LinkButton runat="server" ID="SelectCustomerButton" Text="Auswählen" CommandName="Select" /> <br/>       
        </ItemTemplate> 
       </asp:TemplateField> 

       <asp:TemplateField HeaderText="Kunde" SortExpression="LastName" ItemStyle-VerticalAlign="Top" > 
        <ItemTemplate> 
         <asp:Label ID="NumberLabel" runat="server" Text='<%#"GpNr: " + Eval("Number")%>'></asp:Label><br/> 
         <asp:Label ID="SalutationLabel" runat="server" Text='<%#Eval("Salutation")%>'></asp:Label> 
         <asp:Label ID="TitleLabel" runat="server" Text='<%#Eval("Title")%>'></asp:Label> 
         <asp:Label ID="FirstNameLabel" runat="server" Text='<%#Eval("FirstName")%>'></asp:Label> 
         <asp:Label ID="LastNameLabel" runat="server" Text='<%#Eval("LastName")%>'></asp:Label><br/> 
         <asp:Label ID="NameContactPersonLabel" runat="server" Text='<%#"Kontakt: " + Eval("NameContactPerson")%>'></asp:Label> 
        </ItemTemplate> 
        <ItemStyle VerticalAlign="Top" /> 
       </asp:TemplateField> 
       <asp:TemplateField HeaderText="Adresse" SortExpression="Address.PostalCode" ItemStyle-VerticalAlign="Top" > 
        <ItemTemplate>        
         <asp:Label ID="AddressIdLabel" runat="server" Text = '<%#Eval("Address.Id") %>'></asp:Label> 
         <asp:Label ID="AddressStreetLabel" runat="server" Text='<%#Eval("Address.Street")%>'></asp:Label> 
         <asp:Label ID="AddressHouseNumberLabel" runat="server" Text='<%#Eval("Address.HouseNumber")%>'></asp:Label> 
         <asp:Label ID="AddressHouseNumberExtensionLabel" runat="server" Text='<%#Eval("Address.HouseNumberExtension")%>'></asp:Label> 
         <asp:Label ID="AddressDoorNumberLabel" runat="server" Text='<%#Eval("Address.DoorNumber")%>'></asp:Label><br/> 
         <asp:Label ID="AddressPostalCodeLabel" runat="server" Text='<%#Eval("Address.PostalCode")%>'></asp:Label> 
         <asp:Label ID="AddressCityLabel" runat="server" Text='<%#Eval("Address.City")%>'></asp:Label><br/> 
         <asp:Label ID="AddressCountryLabel" runat="server" Text='<%#Eval("Address.Country")%>'></asp:Label> 
        </ItemTemplate> 

感謝!!

+0

実際のキー値ではなく、インデックスを試してみてください。 - CustomersGridView.DataKeys [CustomersGridView.SelectedIndex] .Values [1 ] ' – deostroll

答えて

0

理由はGridviewはプロパティキーの名前としてdatakeynamesを使用し、DataBinder.Evalは複数のレベルプロパティをサポートしていますが、CreateChildControls()ではDataBinder.GetPropertyValue()を使用しています文字)

例:

object item = ... 
DataBinder.Eval(item, "Address.Id"); //no problem 
DataBinder.GetPropertyValue(item, "Address.Id"); //will throw exception 

あなたの問題を解決するには、いくつかの解決策があります

  1. は、カスタムのGridViewは(CREを上書き導出しますateChildControls())は、データキーイングがマルチレイヤー式をサポートしていることを示します。 Reflectorを使用してデフォルト実装を参照することができます。 (多くの作業)
  2. ストアRowDataBoundイベント中にビューステートへの複雑なプロパティ値(:)好まれ、あまりにも、私が使用する)

例:

private void CustomersGridView_RowDataBound(object sender, EventArgs args) 
{ 
    if(e.Row.RowType = DataControlRowType.DataRow) 
    { 
     object id = DataBinder.Eval(e.Row.DataItem, "Id"); 

     //DictionaryInViewState is a variable that will be stored into viewstate later 
     DictionaryInViewState[id] = DataBinder.Eval(e.Row.DataItem, "Address.Id"); 
    } 
} 

参考文献:

http://www.telerik.com/forums/problem-with-a-complex-datakeynames-value

関連する問題