Ajaxコンボボックス型セルのアイテムにない値を設定してSaveChangesメソッドを呼び出すと値がクリアされる

文書番号 : 40125     文書種別 : 不具合     登録日 : 2017/03/09     最終更新日 : 2017/03/17
文書を印刷する
対象製品
SPREAD for ASP.NET 8.0J
状況
修正済み
詳細
Ajaxコンボボックス型セルのアイテムにない値を設定してSaveChangesメソッドを呼び出すと値がクリアされます。

【再現手順】
1.WebフォームにScriptManager、SPREADコントロール、Buttonコントロールを配置します
2.サンプルコードをコピー&ペーストし

【サンプルコード】
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
  If IsPostBack Then Return

  ' データの作成
  Dim dt As New DataTable("List")
  dt.Columns.Add("ID", GetType(String))
  dt.Columns.Add("Name", GetType(String))
  dt.PrimaryKey = New DataColumn() {dt.Columns("ID")}
  dt.Rows.Add(New Object() {"0", ""})
  For i As Integer = 1 To 4
    dt.Rows.Add(String.Format("{0}", i), String.Format("{0}", ChrW(65 + i)))
  Next
  dt.AcceptChanges()

  ' AjaxComboBoxCellType型セルの設定
  Dim combo As New FarPoint.Web.Spread.Extender.AjaxComboBoxCellType()
  combo.DropDownStyle = AjaxControlToolkit.ComboBoxStyle.DropDown
  combo.DataSource = dt
  combo.DataValueField = dt.Columns(0).ColumnName
  combo.DataTextField = dt.Columns(1).ColumnName
  combo.AutoPostBack = True
  combo.ShowEditor = False
  FpSpread1.ActiveSheetView.Cells(0, 0).CellType = combo
End Sub

Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
  FpSpread1.SaveChanges()
End Sub
回避方法
Service Pack 4(v8.0.4006.2010)で修正済み。
Service Pack 4(v8.0.4006.2010)より前のバージョンでは次の回避方法が有効です。
------------------------------------------

AjaxComboboxCellType型のセルを継承し、内部で保持するアイテムが正しくなるように実装したセル型を使用します。

Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
  If IsPostBack Then Return

  ' データの作成
  Dim dt As New DataTable("List")
  dt.Columns.Add("ID", GetType(String))
  dt.Columns.Add("Name", GetType(String))
  dt.PrimaryKey = New DataColumn() {dt.Columns("ID")}
  dt.Rows.Add(New Object() {"0", ""})
  For i As Integer = 1 To 4
    dt.Rows.Add(String.Format("{0}", i), String.Format("{0}", ChrW(65 + i)))
  Next
  dt.AcceptChanges()

  ' AjaxComboBoxCellType型セルの設定
  'Dim combo As New FarPoint.Web.Spread.Extender.AjaxComboBoxCellType()
  Dim combo As New newAjaxComboBoxCellType()
  combo.DropDownStyle = AjaxControlToolkit.ComboBoxStyle.DropDown
  combo.DataSource = dt
  combo.DataValueField = dt.Columns(0).ColumnName
  combo.DataTextField = dt.Columns(1).ColumnName
  combo.AutoPostBack = True
  combo.ShowEditor = False
  FpSpread1.ActiveSheetView.Cells(0, 0).CellType = combo
End Sub

Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
  FpSpread1.SaveChanges()
End Sub

Class newAjaxComboBoxCellType
  Inherits AjaxComboBoxCellType

  Protected Overrides Function SerializeExtenders(w As System.Xml.XmlTextWriter) As Boolean
    Dim comboBox As ComboBox = TryCast(Extenders(0), ComboBox)
    comboBox.DataBind()
    Return MyBase.SerializeExtenders(w)
  End Function

  Public Overrides Function Parse(s As String) As Object
    Dim comboBox As ComboBox = TryCast(Extenders(0), ComboBox)
    If s Is Nothing Then
      Return Nothing
    End If

    If Me.Items Is Nothing OrElse Me.Items.Count = 0 Then
      Return s
    End If
    For Each item As System.Web.UI.WebControls.ListItem In Items
      If s = item.Text.Trim() Then
        Return item.Value
      End If
    Next

    comboBox.Items.Add(New ListItem(s))
    Return Items.FindByText(s).Value
  End Function

  Public Overrides Function Format(o As Object) As String
    If o Is Nothing AndAlso ShowEditor AndAlso Me.Items IsNot Nothing AndAlso Me.Items.Count > 0 Then
      Dim comboBox As ComboBox = If(Me.Extenders.Count > 0, TryCast(Extenders(0), ComboBox), Nothing)
      Return If(comboBox IsNot Nothing AndAlso comboBox.SelectedIndex = -1, String.Empty, Me.Items(0).ToString())
    End If
    If o Is Nothing Then
      Return ""
    End If

    If Me.Items Is Nothing OrElse Me.Items.Count = 0 Then
      Return o.ToString()
    End If

    Dim item As System.Web.UI.WebControls.ListItem = Items.FindByValue(o.ToString())
    If item IsNot Nothing Then
      Return item.Text
    Else
      Return String.Empty
    End If
  End Function

  Protected Overrides Function DeserializeExtenders(r As System.Xml.XmlNodeReader) As Boolean

    Dim b As Boolean = MyBase.DeserializeExtenders(r)
    Me.DataSource = Nothing
    Return b
  End Function
End Class