type converter and 2 way data binding

Posts   
 
    
jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 28-Aug-2006 21:19:20   

I though I would break this question out. Alex posted a nice type converter here

http://llblgen.com/tinyforum/Messages.aspx?ThreadID=7355

I implemented it in a project and it went pretty well until I tried a form that was databound. It only works 1 way now instead of 2 way. The entity is bound to a combo box with the enum values in it. The entity will update the combo when it changes, but the combo won't update the entity when a user changes the combo. As soon as they tab off of it, it goes back to the entity's value.

the type converter takes a string from the db 0-9 (but in a varchar(1) field) and goes to an account type, asset, liability etc.

the combo is an infragistics combo so it has a valuemember variable and a displaymember variable.

the combo is loaded from a datatable with 2 columns, ID and Values. Values is a string of asset, liability etc.

Id was a string type with 1, 2 etc then it was an int with 1 ,2 etc, then it was typed as the actual enum

none of them worked with 2 way binding. both the int and enum type worked with 1 way. String might have, but I don't remember.

Any ideas?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 29-Aug-2006 10:34:20   

if you set a breakpoint in the setter of the property bound to the combo box (which thus should be called when a value is set through the combobox), is that breakpoint ever hit? If so, do you get an exception, or does SetNewFieldValue return false?

Frans Bouma | Lead developer LLBLGen Pro
jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 29-Aug-2006 14:22:35   

it never gets hit. No errors that I can tell either. It just doesn't seem to take it at all.

Thanks.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 29-Aug-2006 17:42:59   

This happens because the type the value is in in the COMBOBOX isn't compatible with the property you're setting (which has the Enum type). At least that's what I think it is.

Frans Bouma | Lead developer LLBLGen Pro
jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 29-Aug-2006 18:02:56   

Otis wrote:

This happens because the type the value is in in the COMBOBOX isn't compatible with the property you're setting (which has the Enum type). At least that's what I think it is.

Do you have any idea what to try? I tried an int and then actually typing the column as the enum.

see code below.

on the gettype line, I tried string, int and AccountTypeTypeConverter which is the enum. the valuemember is set to return the Id column.

Dim dt As DataTable = New DataTable

        dt.Columns.Add("Id", GetType(AccountTypeTypeConverter))
        dt.Columns.Add("Values", GetType(String))

        Dim dr As DataRow = dt.NewRow
        dr("Id") = AccountTypeTypeConverter.Invalid
        dr("Values") = ""
        dt.Rows.Add(dr)

Thanks!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 30-Aug-2006 10:23:33   

So storing the enum values in the datatable and bind that doesn't work? Hmm... that was the solution I was thinking of. disappointed Odd that using the real enum values doesn't work though...

Frans Bouma | Lead developer LLBLGen Pro
jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 30-Aug-2006 16:52:35   

yeah, you would think it would. can you think of any places to put break points? I've tried several standard ones and it never seems to hit them. I guess it's on the binding somewhere

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 30-Aug-2006 17:29:03   

jspanocsi wrote:

yeah, you would think it would. can you think of any places to put break points? I've tried several standard ones and it never seems to hit them. I guess it's on the binding somewhere

The binding is done by .NET so you can't set a breakpoint in the process. What you might can do is use the SelectedIndexChanged event handler to set the value, but I'm not sure if that will work. Does the combobox have any events you can bind to which might be interesting?

Frans Bouma | Lead developer LLBLGen Pro
jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 05-Sep-2006 19:59:14   

I can reproduce it with a simple form.

drop a datagrid and combo box on a form


Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim col As AccountCollection = New AccountCollection
        Dim filter As IPredicateExpression = New PredicateExpression

        filter.Add(AccountFields.Id >= 5 And AccountFields.Id <= 10)

        col.GetMulti(filter)
        DataGridView1.DataSource = col


        Dim dt As DataTable = New DataTable

        dt.Columns.Add("Id", GetType(AccountTypeTypeConverter))
        dt.Columns.Add("Values", GetType(String))

        Dim dr As DataRow = dt.NewRow
        dr("Id") = AccountTypeTypeConverter.Invalid
        dr("Values") = ""
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("Id") = AccountTypeTypeConverter.Asset
        dr("Values") = "Asset"
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("Id") = AccountTypeTypeConverter.Liability
        dr("Values") = "Liability"
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("Id") = AccountTypeTypeConverter.Equity
        dr("Values") = "Equity"
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("Id") = AccountTypeTypeConverter.Revenue
        dr("Values") = "Revenue"
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("Id") = AccountTypeTypeConverter.CostOfRevenue
        dr("Values") = "Cost of Revenue"
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("Id") = AccountTypeTypeConverter.OtherIncome
        dr("Values") = "Other Income"
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("Id") = AccountTypeTypeConverter.Expenditure
        dr("Values") = "Expenditure"
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("Id") = AccountTypeTypeConverter.OtherFinancingSources
        dr("Values") = "Other Financing Sources"
        dt.Rows.Add(dr)

        dr = dt.NewRow
        dr("Id") = AccountTypeTypeConverter.OtherFinancingUses
        dr("Values") = "Other Financing Uses"
        dt.Rows.Add(dr)

        cboAccountType.DataSource = dt
        cboAccountType.DisplayMember = "Values"
        cboAccountType.ValueMember = "Id"
    End Sub

    Private Sub Binding_format(ByVal sender As Object, ByVal e As ConvertEventArgs)

    End Sub

    Private Sub DataGridView1_RowEnter(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.RowEnter

        If DataGridView1.SelectedRows.Count = 0 Then Return
        Dim act As AccountEntity = DirectCast(DataGridView1.SelectedRows(0).DataBoundItem, AccountEntity)

        cboAccountType.DataBindings.Clear()

        cboAccountType.DataBindings.Add("SelectedValue", act, "AccountType")


    End Sub
End Class




as you move in the grid the combo updates itself to the correct enum value in the combo, but if you change the combo to something else and tab off, it reverts back to the entity value.

don't know if this helps, but i wired in the binding event like last time I had a binding problem Private Sub Binding_format(ByVal sender As Object, ByVal e As ConvertEventArgs) the e.desiredtype is system.object.

Any ideas? Thanks!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 06-Sep-2006 16:48:14   

Isn't this the same issue, the value in the combobox isn't of type enum and / or doesn't match the type of the property to set so .NET's brilliant databinding logic thinks it can't proceed?

Frans Bouma | Lead developer LLBLGen Pro
jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 06-Sep-2006 18:14:59   

Otis wrote:

Isn't this the same issue, the value in the combobox isn't of type enum and / or doesn't match the type of the property to set so .NET's brilliant databinding logic thinks it can't proceed?

I'm not sure. I would hope that binding to dt.Columns.Add("Id", GetType(AccountTypeTypeConverter)) would make the type in the combo the enum.

if I pick a row and then check the type of the combo.selectedvalue I get an integer with the standard dot net control.

I tried changing it to an int for the datatable instead of the enum gettype.

that didn't help it, but the types match now. Using the infragistics combo, the type of the value property is actually the enum

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 07-Sep-2006 11:58:22   

If the type of the ITEM in the combobox is int, it wont' match the type of the property and databinding won't set it.

I still find it odd that the infragistics combobox doesn't set it either. Did you ask infragistics about this? (It's a databinding thing, not llblgen pro related, as the call never reaches the property setter code as you found out).

Frans Bouma | Lead developer LLBLGen Pro
jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 07-Sep-2006 16:14:53   

stupid databinding (did I ever mention I hate databinding simple_smile )

I have it working now this morning. i had to change the datatable definition that the combo is loaded from.

the value field had to be set to a type of object instead of int or the type of the enum.

then I can bind the account type property to it and it works. Don't know what the difference is.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 07-Sep-2006 16:41:59   

aha! Well, it makes sense, as an enum can be casted to an int (has basetype int by default). So if you specify the type as int, the enum values were represented as ints I think.

Frans Bouma | Lead developer LLBLGen Pro