Custom DataGRidComboBoxStyle DataSource Problems

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Richard Ryerson

    #1

    Custom DataGRidComboBoxStyle DataSource Problems

    I have a general DataGridComboBo xColumn that I built using the Example in
    the .NET 2003 Combined Collection help file (that was a data time picker).

    I am able to assign a data source and display / value members so the
    ComboBox is data bound and that works, to a point. What generally works is
    the ComboBox get's populated and the ComboBox shows itself when the
    appropriate column/row is selected. When the ComboBoxColumn isn't selected
    it displays the correct text value (not the related key id value). Alls
    cool, until I bind with a DataSet that contains multiple tables related with
    DataRelations.

    If there are multiple rows, The last row selected properly displays it's
    combobox values / or data values. The other rows display blanks. (I set the
    comboboxcolumn to display blanks when it can't find the correct value in the
    dataset/table/relation.)


    I believe this is because of the DataRelation. There is relational data
    between on column and another, I.e. a customer ship to location applies to a
    single customer. When the last selected row is customer Ford, then the
    Chrysler records display blanks in the customer ship to .

    Because of the DataRelation it is limiting the data that each combo box is
    privy to. And every combo box (shipto's) shares the data source, I believe.

    Anyone have any good ideas on how to 'fix' this anomoly? Any help is greatly
    appreciated.

    Best Regards,

    Rick


  • Ken Tucker [MVP]

    #2
    Re: Custom DataGRidComboBo xStyle DataSource Problems

    Hi,



    Ken
    ------------------
    "Richard Ryerson" <rjryerson@xyzn eo.rr.com> wrote in message
    news:PhnNf.1126 23$tK4.42444@to rnado.ohiordc.r r.com...[color=blue]
    >I have a general DataGridComboBo xColumn that I built using the Example in
    > the .NET 2003 Combined Collection help file (that was a data time picker).
    >
    > I am able to assign a data source and display / value members so the
    > ComboBox is data bound and that works, to a point. What generally works is
    > the ComboBox get's populated and the ComboBox shows itself when the
    > appropriate column/row is selected. When the ComboBoxColumn isn't selected
    > it displays the correct text value (not the related key id value). Alls
    > cool, until I bind with a DataSet that contains multiple tables related
    > with
    > DataRelations.
    >
    > If there are multiple rows, The last row selected properly displays it's
    > combobox values / or data values. The other rows display blanks. (I set
    > the
    > comboboxcolumn to display blanks when it can't find the correct value in
    > the
    > dataset/table/relation.)
    >
    >
    > I believe this is because of the DataRelation. There is relational data
    > between on column and another, I.e. a customer ship to location applies to
    > a
    > single customer. When the last selected row is customer Ford, then the
    > Chrysler records display blanks in the customer ship to .
    >
    > Because of the DataRelation it is limiting the data that each combo box is
    > privy to. And every combo box (shipto's) shares the data source, I
    > believe.
    >
    > Anyone have any good ideas on how to 'fix' this anomoly? Any help is
    > greatly
    > appreciated.
    >
    > Best Regards,
    >
    > Rick
    >
    >[/color]


    Comment

    • Richard Ryerson

      #3
      Re: Custom DataGRidComboBo xStyle DataSource Problems

      Yeah, I am able to display the "words" but state is being lost when selected
      "row" changes in the datagrid, due to the relation performing it's job. I
      need a viable way to save previous states and call upon that.


      "Ken Tucker [MVP]" <vb2ae@bellsout h.net> wrote in message
      news:eOoB2IYPGH A.3856@TK2MSFTN GP12.phx.gbl...[color=blue]
      > Hi,
      >
      >[/color]
      http://www.vb-tips.com/default.aspx?...6-7320e41e6d05[color=blue]
      >
      > Ken
      > ------------------
      > "Richard Ryerson" <rjryerson@xyzn eo.rr.com> wrote in message
      > news:PhnNf.1126 23$tK4.42444@to rnado.ohiordc.r r.com...[color=green]
      > >I have a general DataGridComboBo xColumn that I built using the Example in
      > > the .NET 2003 Combined Collection help file (that was a data time[/color][/color]
      picker).[color=blue][color=green]
      > >
      > > I am able to assign a data source and display / value members so the
      > > ComboBox is data bound and that works, to a point. What generally works[/color][/color]
      is[color=blue][color=green]
      > > the ComboBox get's populated and the ComboBox shows itself when the
      > > appropriate column/row is selected. When the ComboBoxColumn isn't[/color][/color]
      selected[color=blue][color=green]
      > > it displays the correct text value (not the related key id value). Alls
      > > cool, until I bind with a DataSet that contains multiple tables related
      > > with
      > > DataRelations.
      > >
      > > If there are multiple rows, The last row selected properly displays it's
      > > combobox values / or data values. The other rows display blanks. (I set
      > > the
      > > comboboxcolumn to display blanks when it can't find the correct value in
      > > the
      > > dataset/table/relation.)
      > >
      > >
      > > I believe this is because of the DataRelation. There is relational data
      > > between on column and another, I.e. a customer ship to location applies[/color][/color]
      to[color=blue][color=green]
      > > a
      > > single customer. When the last selected row is customer Ford, then the
      > > Chrysler records display blanks in the customer ship to .
      > >
      > > Because of the DataRelation it is limiting the data that each combo box[/color][/color]
      is[color=blue][color=green]
      > > privy to. And every combo box (shipto's) shares the data source, I
      > > believe.
      > >
      > > Anyone have any good ideas on how to 'fix' this anomoly? Any help is
      > > greatly
      > > appreciated.
      > >
      > > Best Regards,
      > >
      > > Rick
      > >
      > >[/color]
      >
      >[/color]


      Comment

      • Richard Ryerson

        #4
        Re: Custom DataGRidComboBo xStyle DataSource Problems

        Here is the scenario.

        Customers (Id, Name)
        -------------
        1, Ford
        2, Chrysler

        ShipTos (Id, CustId, Location)
        ---------
        1, 1, XYZ
        2, 1, PDQ
        3, 2, FAQ
        4, 2, ROF

        There is a relation between Customers and ShipTos (Customers.Id ->
        ShipTos.CustId)

        Now main DataTable (Releases) contains info pertaining to Customers and
        ShipTos

        Releases (Id, CustId, ShipToId, Qty)
        ----------
        1, 1, 1, 5000 (1, Ford, XYZ, 5000)
        2, 2, 4, 2500 (2, Chrysler, ROF, 2500)

        When the data grid first displays, it only displays complete information for
        the second row, because this is the last row in the grid, and therefore the
        last DataRelation view set i'll call it. The First record does not display
        correctly because it's data is violating the DataRelation constraints.
        (ShipTo XYZ does not relate to Chrysler). So, that column gets displayed as
        a blank, because to display the 'word' you must traverse or find the 'word'
        by the key (1) in the current view.

        It appears that each ComboBox 'shares' it's properties / data whatever
        regardless of the row. I need a way to search the correct Relation or
        remember (bad code) the previous data relation information. I've tried
        storing the data/state in a hashtable, but it seems to not work.

        Here is the code for the ComboBoxColumn. It needs to be as extendable /
        useful as possible. Meaning I can't design this comboboxstyle to work ONLY
        in this situation.

        Best regards,

        Rick

        Imports System.Componen tModel

        Public Class DataGridComboBo xColumn

        Inherits DataGridColumnS tyle

        Private _isEditing As Boolean = False

        Private WithEvents _comboBox As ComboBox

        Private _dataSource As Object

        Private _dataMember As String

        Private _valueMember As String

        Private _displayMember As String

        Private _lists As Hashtable

        Protected Sub OnPropertyChang ed(ByVal e As PropertyChanged EventArgs)

        Select Case e.PropertyName

        Case "DataSource "

        _comboBox.DataS ource = _dataSource

        Case "ValueMembe r"

        If _dataMember Is Nothing Then

        _comboBox.Value Member = _valueMember

        Else

        _comboBox.Value Member = String.Format(" {0}.{1}", _dataMember, _valueMember)

        End If

        Case "DisplayMem ber"

        If _dataMember Is Nothing Then

        _comboBox.Displ ayMember = _displayMember

        Else

        _comboBox.Displ ayMember = String.Format(" {0}.{1}", _dataMember,
        _displayMember)

        End If

        End Select

        Invalidate()

        End Sub

        Public ReadOnly Property DataBindings() As ControlBindings Collection

        Get

        Return _comboBox.DataB indings

        End Get

        End Property

        Public Property DataSource() As Object

        Get

        Return _dataSource

        End Get

        Set(ByVal Value As Object)

        _dataSource = Value

        OnPropertyChang ed(New PropertyChanged EventArgs("Data Source"))

        End Set

        End Property

        Public Property ValueMember() As String

        Get

        Return _valueMember

        End Get

        Set(ByVal Value As String)

        _valueMember = Value

        OnPropertyChang ed(New PropertyChanged EventArgs("Valu eMember"))

        End Set

        End Property

        Public Property DisplayMember() As String

        Get

        Return _displayMember

        End Get

        Set(ByVal Value As String)

        _displayMember = Value

        OnPropertyChang ed(New PropertyChanged EventArgs("Disp layMember"))

        End Set

        End Property

        Public Property DataMember() As String

        Get

        Return _dataMember

        End Get

        Set(ByVal Value As String)

        _dataMember = Value

        OnPropertyChang ed(New PropertyChanged EventArgs("Data Member"))

        End Set

        End Property

        Public Sub New()

        _comboBox = New ComboBox

        _lists = New Hashtable

        _comboBox.Visib le = False

        End Sub

        Protected Overrides Sub Abort(ByVal rowNum As Integer)

        _isEditing = False

        DataGridTableSt yle.DataGrid.In validate(_combo Box.Bounds)

        End Sub

        Protected Overrides Function Commit(ByVal dataSource As
        System.Windows. Forms.CurrencyM anager, ByVal rowNum As Integer) As Boolean

        _comboBox.Bound s = Rectangle.Empty

        If Not _isEditing Then

        Return True

        End If

        _isEditing = False

        Try

        Dim value As Object

        value = _comboBox.Selec tedValue

        If NullText.Equals (value) Then

        value = System.Convert. DBNull

        End If

        SetColumnValueA tRow(dataSource , rowNum, value)

        Catch ex As Exception

        End Try

        DataGridTableSt yle.DataGrid.In validate(_combo Box.Bounds)

        Return True

        End Function

        Protected Overloads Overrides Sub Edit(ByVal source As
        System.Windows. Forms.CurrencyM anager, ByVal rowNum As Integer, ByVal bounds
        As System.Drawing. Rectangle, ByVal [readOnly] As Boolean, ByVal instantText
        As String, ByVal cellIsVisible As Boolean)

        Dim value As Object = GetText(GetColu mnValueAtRow(so urce, rowNum))

        If cellIsVisible Then

        _comboBox.Bound s = New Rectangle(bound s.X + 2, bounds.Y + 2, bounds.Width -
        4, bounds.Height - 4)

        _comboBox.Visib le = True

        Else

        _comboBox.Visib le = False

        End If

        If _comboBox.Visib le Then

        DataGridTableSt yle.DataGrid.In validate(bounds )

        End If

        End Sub

        Protected Overrides Function GetMinimumHeigh t() As Integer

        Return _comboBox.Prefe rredHeight + 4

        End Function

        Protected Overrides Function GetPreferredHei ght(ByVal g As
        System.Drawing. Graphics, ByVal value As Object) As Integer

        Return _comboBox.Prefe rredHeight + 4

        End Function

        Protected Overrides Function GetPreferredSiz e(ByVal g As
        System.Drawing. Graphics, ByVal value As Object) As System.Drawing. Size

        Return New Size(_comboBox. Width + 4, _comboBox.Prefe rredHeight + 4)

        End Function

        Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing. Graphics,
        ByVal bounds As System.Drawing. Rectangle, ByVal source As
        System.Windows. Forms.CurrencyM anager, ByVal rowNum As Integer)

        Paint(g, bounds, [source], rowNum, False)

        End Sub

        Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing. Graphics,
        ByVal bounds As System.Drawing. Rectangle, ByVal source As
        System.Windows. Forms.CurrencyM anager, ByVal rowNum As Integer, ByVal
        alignToRight As Boolean)

        Paint(g, bounds, [source], rowNum, Brushes.Red, Brushes.Blue, alignToRight)

        End Sub

        Protected Overloads Overrides Sub Paint(ByVal g As Graphics, ByVal bounds As
        Rectangle, ByVal [source] As CurrencyManager , ByVal rowNum As Integer, ByVal
        backBrush As Brush, ByVal foreBrush As Brush, ByVal alignToRight As Boolean)

        Dim value As Object = GetColumnValueA tRow([source], rowNum)

        Dim rect As Rectangle = bounds

        Dim s As String = Nothing

        Dim displayMem As String

        Dim valueMem As String

        If _lists(rowNum) Is Nothing Then

        Dim col(_comboBox.I tems.Count - 1) As Object

        _comboBox.Items .CopyTo(col, 0)

        _lists.Add(rowN um, col)

        End If

        'loop through the items of the combo box

        'this items collection seems to be shared

        'between all the instances of the same

        'column of combo boxes.

        Dim col2() As Object = _lists(rowNum)

        For Each drv As DataRowView In _comboBox.Items

        If _valueMember.In dexOf(_dataMemb er) > -1 Then

        'remove the Parent.Relation . from the value member

        valueMem = _valueMember.Re place(_dataMemb er, "").Remove( 0, 1)

        Else

        valueMem = _valueMember

        End If



        If _displayMember. IndexOf(_dataMe mber) > -1 Then

        'remove the Parent.Relation . from the display member

        displayMem = _displayMember. Replace(_dataMe mber, "").Remove( 0, 1)

        Else

        displayMem = _displayMember

        End If

        'make sure it's not a added row

        If Not value Is Nothing AndAlso Not value Is System.DBNull.V alue Then

        If drv(valueMem) = value Then

        Try

        s = drv(displayMem)

        Catch ex As Exception

        s = value

        End Try

        Exit For

        End If

        Else

        s = Me.NullText

        Exit For

        End If

        Next

        g.FillRectangle (backBrush, rect)

        rect.Offset(0, 2)

        rect.Height -= 2

        If Not s Is Nothing Then

        If value Is Nothing Then

        s = NullText

        End If

        Try

        g.DrawString(s. ToString, Me.DataGridTabl eStyle.DataGrid .Font, foreBrush,
        RectangleF.From LTRB(rect.X, rect.Y, rect.Right, rect.Bottom))

        Catch ex As Exception

        Debug.WriteLine (ex.ToString)

        End Try

        End If

        End Sub

        Protected Overrides Sub SetDataGridInCo lumn(ByVal value As DataGrid)

        MyBase.SetDataG ridInColumn(val ue)

        If Not (_comboBox.Pare nt Is Nothing) Then

        _comboBox.Paren t.Controls.Remo ve(_comboBox)

        End If

        If Not (value Is Nothing) Then

        value.Controls. Add(_comboBox)

        End If

        End Sub

        Public Overrides Property Width() As Integer

        Get

        Return MyBase.Width

        End Get

        Set(ByVal Value As Integer)

        MyBase.Width = Value

        _comboBox.Width = Value - 4

        End Set

        End Property

        Private Function GetText(ByVal value As Object) As String

        If value Is System.DBNull.V alue Then

        Return Me.NullText

        Else

        If Not value Is Nothing Then

        Return value.ToString

        Else

        Return String.Empty

        End If

        End If

        End Function

        Private Sub _comboBox_Selec tedIndexChanged (ByVal sender As Object, ByVal e
        As System.EventArg s) Handles _comboBox.Selec tedIndexChanged

        _isEditing = True

        MyBase.ColumnSt artedEditing(_c omboBox)

        End Sub

        End Class




        Best regards,

        Rick


        Comment

        Working...