それぞれ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参照例外が返されます