2

それぞれ2つの別々のSqlDataSourceにバインドしようとしている2つのカスケードドロップダウンリストがあります。

これらのドロップダウンリストは、FormViewのEditItemTemplateにあります。EditItemTemplate内には、部門とジョブ名を設定する2つのsqldatasourceコントロールが存在します。DeptIDとJobIDは、これらのテーブルの主キーです。これにより、部門と職務の間に「カスケード効果」が生まれます。部門を選択すると、その部門に関連付けられているジョブのみが表示されます。

この作品は正常に動作しています。

<asp:FormView ID="frmProfile" runat="server" DataSourceID="sqlDSProfile" 
    DataKeyNames="EUID" style="margin-top: 0px">
    <EditItemTemplate>
        <asp:DropDownList ID="ddlDepartments" runat="server" Width="135px"
            DataSourceID="sqlDSDepartments" 
            DataTextField="Department" 
            DataValueField="DeptID" AutoPostBack="True" 
            SelectedValue='<%# Bind("CurrentDeptID") %>' 
            AppendDataBoundItems="true" >
                <asp:ListItem></asp:ListItem>
        </asp:DropDownList>

        <asp:DropDownList ID="ddlJobNames" runat="server" Width="185px"
            DataSourceID="sqlDSJobs" DataTextField="JobName" DataValueField="JobID" 
            SelectedValue='<%# Bind("CurrentJobID") %>' 
            AppendDataBoundItems="true" >
                <asp:ListItem></asp:ListItem>
        </asp:DropDownList>

        <asp:SqlDataSource ID="sqlDSDepartments" runat="server" 
            ConnectionString="<%$ ConnectionStrings:JobsDB %>" 
            SelectCommand="SELECT tblDepartments.DeptID, 
                                  tblDepartments.Department 
                           FROM tblDepartments" />

        <asp:SqlDataSource ID="sqlDSJobs" runat="server" 
            ConnectionString="<%$ ConnectionStrings:JobsDB %>" 
            SelectCommand="SELECT tblJobs.JobID, tblJobs.JobName FROM tblJobs
                           INNER JOIN tblDeptsJobs ON tblDeptsJobs.JobID = tblJobs.JobID
                           WHERE tblDeptsJobs.DeptID = @DeptID" >
            <SelectParameters>
                <asp:ControlParameter ControlID="ddlDepartments" Name="DeptID" 
                    PropertyName="SelectedValue" />
            </SelectParameters>
        </asp:SqlDataSource>
    </EditItemTemplate>
</asp:FormView>

フォームビューの外部には、更新ステートメントですべての情報をEmployeeテーブルにバインドするSqlDataSourceが存在します。上記のFormViewから省略されている場合でも、このSqlDataSourceに他のすべての情報を残しています。

<asp:SqlDataSource ID="sqlDSProfile" runat="server" 
    ConnectionString="<%$ ConnectionStrings:JobsDB %>" 
    SelectCommand="SELECT tblEmployee.EUID, 
                tblEmployee.DateHired, 
                tblEmployee.LastName, 
                tblEmployee.HiredLastName, 
                tblEmployee.FirstName, 
                tblEmployee.Role, 
                tblEmployee.JobGrade, 
                tblEmployee.CurrentDeptID, 
                tblDepartments.Department, 
                tblDepartments.DeptID, 
                tblEmployee.CurrentJobID, 
                tblJobs.JobName, 
                tblJobs.JobID, 
                tblEmployee.CurrentShift, 
                tblEmployee.JobDate, 
                tblEmployee.IsDisplaced, 
                tblEmployee.EligibilityDate 
            FROM tblEmployee 
                LEFT OUTER JOIN tblDepartments ON tblEmployee.CurrentDeptID = tblDepartments.DeptID 
                EFT OUTER JOIN tblJobs ON tblEmployee.CurrentJobID = tblJobs.JobID 
            WHERE (tblEmployee.EUID = @EUID)"
    UpdateCommand="UPDATE [tblEmployee] 
                SET [tblEmployee].[DateHired] = @DateHired, 
                    [tblEmployee].[LastName] = @LastName, 
                    [tblEmployee].[HiredLastName] = @HiredLastName, 
                    [tblEmployee].[FirstName] = @FirstName, 
                    [tblEmployee].[Role] = @Role, 
                    [tblEmployee].[JobGrade] = @JobGrade, 
                    [tblEmployee].[CurrentDeptID] = @CurrentDeptID, 
                    [tblEmployee].[CurrentJobID] = @CurrentJobID, 
                    [tblEmployee].[CurrentShift] = @CurrentShift, 
                    [tblEmployee].[JobDate] = @JobDate, 
                    [tblEmployee].[IsDisplaced] = @IsDisplaced, 
                    [tblEmployee].[EligibilityDate] = @EligibilityDate 
                WHERE [tblEmployee].[EUID] = @EUID"
                    ProviderName="System.Data.SqlClient">
    <SelectParameters>
        <asp:SessionParameter Name="EUID" SessionField="sProfileEUID" DbType="String" />
    </SelectParameters>
    <UpdateParameters>
        <asp:Parameter Name="DateHired" DbType="Date" />
        <asp:Parameter Name="LastName" DbType="String" />
        <asp:Parameter Name="HiredLastName" DbType="String" />
        <asp:Parameter Name="FirstName" DbType="String" />
        <asp:Parameter Name="Role" DbType="String" />
        <asp:Parameter Name="JobGrade" DbType="Byte" />
        <asp:Parameter Name="CurrentDeptID" DbType="Int32" />
        <asp:Parameter Name="CurrentJobID" DbType="Int32" />
        <asp:Parameter Name="CurrentShift" DbType="Int32" />
        <asp:Parameter Name="JobDate" DbType="Date" />
        <asp:Parameter Name="IsDisplaced" DbType="Boolean"/>
        <asp:Parameter Name="EligibilityDate" DbType="Date"/>
        <asp:SessionParameter Name="EUID" SessionField="sProfileEUID" DbType="String" />
    </UpdateParameters>
</asp:SqlDataSource>

バインドする方法がわからないのは、部門とジョブだけです。他のすべてが機能しています。DropDownListコントロールで次のコードを使用してみました...

SelectedValue='<%# Bind("CurrentDeptID") %>'
SelectedValue='<%# Bind("CurrentJobID") %>'

...しかし、これらはエラーになります。

概要

ユーザーが[編集]をクリックすると、メインのsqlDSProfileデータソースから選択した値を取得するために2つのドロップダウンボックスの値が必要になりますが、更新可能である必要があります。アソシエイトが属するジョブを更新してバインドできるようになりましたが、ドロップダウンリストがカスケードされるため、部門を変更しようとすると、AutoPostBackがsqlDSProfile-CurrentJobIDとddlJobsの間のバインドを解除します。

アップデート

selectステートメントにとを追加し、DropDownListコントロールにBind()ステートメントを追加しましtblEmployee.CurrentDeptIDた。tblEmployee.CurrentJobID

SelectedValue='<%# Bind("CurrentDeptID") %>' 
SelectedValue='<%# Bind("CurrentJobID") %>' 

これで、2つのDropDownListに、Employeeテーブルから取得した正確な情報が入力され、従業員が属する部門とジョブが示されます。

2つのDropDownListには、FormView内の2つのSqlDataSourceも入力され、部門を変更したり、ジョブを変更したりするためのオプションが提供されます。

ジョブを変更すると、それが機能し、従業員のジョブが更新されます。

学科を変えると壊れてDataBinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.

完了に近い

ddlJobsからデータバインディングを削除し、バックグラウンドでコーディングしました。

Protected Sub frmProfile_ItemUpdating(sender As Object, e As System.Web.UI.WebControls.FormViewUpdateEventArgs) Handles frmProfile.ItemUpdating
    If frmProfile.CurrentMode = FormViewMode.Edit Then
        e.NewValues("CurrentJobID") = DirectCast(DirectCast(sender, FormView).FindControl("ddlJobs"), DropDownList).SelectedValue
    End If
End Sub

残っているのは、ddlDepartmentsが変更されたときのコードを作成することだけです。

擬似コード...

    ' If Item exists in ddlJobs Then
    '   select item (CurrentJobID)
    ' else
    '   select index 0 and make them pick something new
    ' end if

とても近い!

再度更新

これは、これを緩くバインドするために私が開発したコードです。page_loadで、sqlDSProfileからCurrentJobIDの内容を取得し、その値がddlJobsに存在するかどうかを確認しようとしています。もしそうなら、ddlJobs.SelectedValue=をそのCurrentJobIDに設定したいと思います。そうでない場合は、selectedindexを0に設定します。これは、「1つ選択してください」などのメッセージです。

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If frmProfile.CurrentMode = FormViewMode.Edit Then

        ' Need to determine if the CurrentJobID returned in the select statement
        ' exists in the ddlJobs dropdownlist.  If it does, set that to the
        ' selectedvalue, if not set it to 0 so the user can select a new job.

        Dim ddlJobs As DropDownList = frmProfile.FindControl("ddlJobs")
        Dim dvProfile As DataView = sqlDSProfile.Select(DataSourceSelectArguments.Empty)
        Dim drvProfile As DataRowView = dvProfile(0)

        If ddlJobs.Items.FindByValue(drvProfile("CurrentJobID")) Is DBNull.Value Then
            ddlJobs.SelectedIndex = 0
        Else
            ddlJobs.SelectedValue = drvProfile("CurrentJobID")
        End If

    End If

End Sub

dbnull.valueをチェックしている行でnull参照例外が返されます

4

3 に答える 3

4

私は同様の問題を抱えていて、非常に単純な解決策を見つけました(そしてc#で)。カテゴリテーブルとサブカテゴリテーブル(これらも関連し、制約されています)に関連するテーブルQuestionsを持つデータベースを想像してみてください。既存のレコードを更新しようとすると、aspはエラーをスローします。これは、Lucretiusetalからの上記の情報のおかげで私が解決した解決策です。

  1. 親ドロップダウンリストのみをデータバインド
  2. データソースの更新イベントに子ドロップダウンで選択した値を挿入する方法を見つけます。

として:

 protected void odseditquestion_Updating(object sender, ObjectDataSourceMethodEventArgs e)
    {
        //dynamically assign value from ddlsubcategory to odseditquestion on updating event
        //you really should not have to do this
        DropDownList ddlsubcategory = (DropDownList)fveditquestion.FindControl("ddlsubcategory");
        e.InputParameters["subcatid"] = (ddlsubcategory.SelectedValue);
    }

それは私のアプリケーションで動作します。それが誰かを助けることを願っています、これは私に半日かかりました、それはaspです!!

于 2012-12-12T22:59:55.353 に答える
2

問題は、updateステートメントtlbEmployeeの列とSqlDSProfile コントロールで使用されるフィールド名が一致しない場合に発生する可能性があります。あなたが従った他の手順は正しいです。

SqlDataSource control expects field names it updates to be similar with those bound to the controls(fields) inside the DataBound control.

解決策は次のとおりです。すべての更新を、それぞれに適切なコントロールを参照するように変更しParametersますControlParameter

更新:待ってください。問題は、SqlDSProfileのselectステートメントに次のものが含まれていることだと思います:CurrentDeptIDおよびCurrentJobID。それを試してみてください:

<asp:SqlDataSource ID="sqlDSProfile" runat="server" 
ConnectionString="<%$ ConnectionStrings:JobsDB %>" 
SelectCommand="SELECT tblEmployee.EUID, 
            tblEmployee.DateHired, 
            tblEmployee.LastName, 
            tblEmployee.HiredLastName, 
            tblEmployee.FirstName, 
            tblEmployee.Role, 
            tblEmployee.JobGrade, 
            tblDepartments.Department, 
            tblJobs.JobName, 
            tblEmployee.CurrentShift, 
            tblEmployee.JobDate, 
            tblEmployee.IsDisplaced, 
            tblEmployee.EligibilityDate 
            tblEmployee.CurrentDeptID, 
            tblEmployee.CurrentJobID 
        FROM tblEmployee 

アドバイス:コードを部分的にテストします。
ドロップダウンリストなしでコードを試してください。個別にテストして
ください。1つのドロップダウンリストを追加して ください 。select
クエリでselect*from...を使用して ください。
テスト時にajaxを避けてください。


于 2012-02-07T19:15:12.143 に答える
1

Nuuxとたくさんのオンライン調査のおかげで、私は今、実用的な解決策を持っています。結合ステートメントに関するヒントは関係ありませんでしたが、選択クエリに「CurrentJobID」と「CurrentDeptID」を含めることに関するヒントは的を射ていました。

それに加えて、コントロールを少し作り直さなければなりませんでした。2つのカスケードドロップダウンリストを以下に示します。ddlJobsドロップダウンリストは通常​​のデータバインドされたコントロールのように動作しますが、元の投稿で試していたBind( "CurrentJobID")ステートメントがありません。

<asp:DropDownList ID="ddlDepartments" runat="server" Width="185px" 
    DataSourceID="sqlDSDepartments" 
    DataTextField="Department" 
    DataValueField="DeptID" 
    SelectedValue='<%# Bind("CurrentDeptID") %>' 
    AppendDataBoundItems="true" 
    AutoPostBack="True" >
        <asp:ListItem Text="--Select One--" Value="" />                                                
</asp:DropDownList>

<asp:DropDownList ID="ddlJobs" runat="server" Width="185px"
    DataSourceID="sqlDSJobs" 
    DataTextField="JobName" 
    DataValueField="JobID" 
    AppendDataBoundItems="true" 
    OnDataBinding="ddlJobs_DataBinding" />

カスタムルーチン「ddlJobs_DataBinding」が実行しているのは、ddlJobsドロップダウンのインデックス0として「--SelectOne--」を追加することだけです。page_loadやformviewのデータバインドイベントなど、いくつかの場所でこれを試しましたが、成功しませんでした。

Protected Sub ddlJobs_DataBinding(sender As Object, e As System.EventArgs)

    Dim ddlJobs As DropDownList = frmProfile.FindControl("ddlJobs")
    Dim liSelectOne As New ListItem("--Select One--", 0)

    ddlJobs.Items.Clear()
    ddlJobs.Items.Insert(0, liSelectOne)

End Sub

ただし、formviewfrmProfile_DataBoundイベントのデータバインドイベントはいくつかの作業を行います。ユーザーがフォームビューで[編集]をクリックして編集モードに入ると、ドロップダウンリストddlJobsで、問題のプロファイルに対してデフォルトで正しいジョブが選択されていることが保証されます。ユーザーがジョブに割り当てられていない場合、デフォルトでselectedindex 0になります。これは、すぐ上のカスタムデータバインディングイベントで設定された「--SelectOne--」です。

Protected Sub frmProfile_DataBound(sender As Object, e As System.EventArgs) Handles frmProfile.DataBound

    If frmProfile.CurrentMode = FormViewMode.Edit Then

        Dim ddlJobs As DropDownList = frmProfile.FindControl("ddlJobs")
        Dim dvProfile As DataView = sqlDSProfile.Select(DataSourceSelectArguments.Empty)
        Dim drProfile As DataRow = dvProfile.Table.Rows(0)

        If drProfile("CurrentJobID").ToString() = "" Then
            ddlJobs.SelectedIndex = 0
        Else
            ddlJobs.SelectedValue = drProfile("CurrentJobID").ToString()
        End If

    End If

End Sub

最後に、ユーザーがddlJobsから新しいジョブを選択した場合、その値をデータベースにフィードする必要があります。データベースは、formviewのItemUpdatingイベントが処理します。

Protected Sub frmProfile_ItemUpdating(sender As Object, e As System.Web.UI.WebControls.FormViewUpdateEventArgs) Handles frmProfile.ItemUpdating

    If frmProfile.CurrentMode = FormViewMode.Edit Then

        Dim ddlJobs As DropDownList = frmProfile.FindControl("ddlJobs")
        e.NewValues("CurrentJobID") = ddlJobs.SelectedValue

    End If

End Sub

終わり!

于 2012-02-10T03:18:11.540 に答える