Thoughts and Opinions Welcome

Posts   
 
    
MarcoP avatar
MarcoP
User
Posts: 270
Joined: 29-Sep-2004
# Posted on: 21-Jul-2006 15:41:45   

I found myself writing the same code over and over again in the UI layer:


if (txtName.Text == string.empty)
   entity.SetNewFieldValue((int)CustomerFieldIndex.Name, null);
else
   entity.Name = txtName.Text;

So, I had this type of code sprinkled throughout the application (note, i didn't just check string types, but all the various db types). So, my solution was that since I already had for example, BaseTextBox and BaseComboBox controls (plus more), I overrided for example the Text and Value properties, so when I call the property, I get back the LLBL null equivalent if the control doesn't have a value.

Next, in the data access adapter, I overrided the SaveEntity method to call the following method I wrote to auto-assign nulls:


        private void AssignNulls(IEntity2 entity)
        {
            for (int i = 0; i < entity.Fields.Count; i++)
            {
                IEntityField2 field = entity.Fields[i];
                if (!field.DataType.Equals(typeof(bool)) && field.CurrentValue != null)
                {
                    if (field.IsNullable && !field.IsReadOnly && !field.IsPrimaryKey)
                    {
                        if (field.IsChanged && field.CurrentValue.Equals(TypeDefaultValue.GetDefaultValue(field.DataType)))
                        {
                            entity.SetNewFieldValue(i, null);
                        }
                    }
                }
            }
        }

Now, in my UI layer, all the code I need to write is:


cust.FirstName = txtFirstName.Text;
cust.Age = numericEditor.Value;

custManager.Save(cus);
etc..

Just wondering what you guys do (or even worry about) in your current applications. Also note, my custom controls expose an EntityField property that I set in my Form_Load event, so the controls automatically set their max length fields, display an '*' next to required fields, etc..

Posts: 94
Joined: 26-Feb-2006
# Posted on: 21-Jul-2006 18:55:27   

Well Marco, if it would be c# I would think its my code (I am using VB.net) !

Obvoisly I have come to the same result althouhg that I use copy&paste for this repititive task (but you are right it´s worst kind of ugly code!)

Would you mind sharing some details of your Custom WebControls?

Adrian

MarcoP avatar
MarcoP
User
Posts: 270
Joined: 29-Sep-2004
# Posted on: 21-Jul-2006 21:19:59   

adrianporger wrote:

Well Marco, if it would be c# I would think its my code (I am using VB.net) !

Obvoisly I have come to the same result althouhg that I use copy&paste for this repititive task (but you are right it´s worst kind of ugly code!)

Would you mind sharing some details of your Custom WebControls?

Adrian

Sure, here is an example of some of my code:


// here is my derived combobox (note, i am using infragistics)

        /// <summary>
        /// Sets the entity field.
        /// </summary>
        public IEntityField2 Field
        {
            set
            {
                _field = value;
                WinFormsUtility.SetControlProperties(value, this);
            }
        }

        /// <summary>
        /// Gets the current value.
        /// </summary>
        public override object Value
        {
            get
            {
                if (_field != null && (base.Value == null || base.Value.Equals(Null.GetDefaultValue(_field.DataType))))
                {
                    return Null.GetDefaultValue(_field.DataType);
                }
                else
                {
                    return base.Value;
                }
            }
            set
            {
                base.Value = value;
            }
        }

Here is one of my utility classes:


    public static class WinFormsUtility
    {
        private static System.Windows.Forms.ToolTip _tooltip = new System.Windows.Forms.ToolTip();

        static WinFormsUtility()
        {
            _tooltip.IsBalloon = true;
            _tooltip.ToolTipIcon = ToolTipIcon.Info;
            _tooltip.ToolTipTitle = Properties.Resources.RequiredToolTip;       
        }

        public static UltraLabel GetRequiredFieldLabel(Control control, IEntityField2 field)
        {
            UltraLabel requiredLabel = new UltraLabel();
            requiredLabel.Text = "*";
            requiredLabel.AutoSize = true;
            requiredLabel.Appearance.ForeColor = Color.Maroon;
            requiredLabel.Location = new Point(control.Right + 3, control.Top + (control.Font.Height / 2));
            _tooltip.SetToolTip(requiredLabel, string.Format(Properties.Resources.RequiredField, LLBLHelper.ResolveFieldName(field)));
            return requiredLabel;
        }

        public static void SetControlProperties(IEntityField2 field, Control control)
        {
            if (control is UltraTextEditor)
            {
                UltraTextEditor editor = (UltraTextEditor)control;
                editor.MaxLength = field.MaxLength;
                editor.ReadOnly = field.IsReadOnly || field.IsPrimaryKey;
            } 
            else if (control is UltraNumericEditor)
            {
                UltraNumericEditor editor = (UltraNumericEditor)control;
                editor.Nullable = field.IsNullable;
            }  

            if (!field.IsNullable)
            {
                control.Parent.Controls.Add(GetRequiredFieldLabel(control, field));
            }       
        }
    }

vzwMann
User
Posts: 6
Joined: 28-Mar-2007
# Posted on: 20-Apr-2007 18:40:59   

I am building a framwork to solve the same problem of repetitive tasks. Although I did mine in vb.net. Don't frown upon my vb.net, it is easier for everyone to read all around, I hope!

What I do is pass name the controls mapped to table column names (I threw out VB naming convention) with an optional naming convention (prefix+column name) or I make a dictionary of custom names (I use [name] as a column name and that is a .net keyword or creates problems, the key is the custom name, the value is the table column name). This allows me to customize my naming convention on my forms in anyway I see fit. The functions then loop through all the controls on the form or group box plus their child controls, see if control name matches a objEntity property name and if so set or retrieve value.

I map the names of the control to the names of the table columns, pass the by Ref the form or group box, the objEntity I am working with and waaaLaa!!! All I do in the future is use that same class pass in three params and I am done! Now I can really be lazy (effecient) in future code. I also have a couple helper functions. One last things, I pass the objEntity by reference because you should set all your primary or foriegn keys to the object prior to binding or saving the objEntity values.

Please bare with me, this is my first version and there are many places I can reduce code and speed it up. When I am done (cleaning it up) I will be posting that. Here it is, I hope this helps you. [Note the view functions uses a group box, you can easily change it to a form]

'---view function
Public Function bindToProjectObj(ByRef grpBox As GroupBox, ByRef objEntity As EntityBase2, ByRef CustNames As Dictionary(Of String, String), Optional ByVal Prefix As String = "") As String
        'Data object
        Dim adptr As DL.DatabaseSpecific.DataAccessAdapter
        'Windows Form Controls
        Dim control As System.Windows.Forms.Control
        Dim childControl As System.Windows.Forms.Control
        Dim tmpDrpDown As System.Windows.Forms.ComboBox
        Dim tmpCalendar As System.Windows.Forms.DateTimePicker
        Dim tmpNumeric As System.Windows.Forms.NumericUpDown
        Dim tmpUltraCmb As Infragistics.Win.UltraWinGrid.UltraCombo
        Dim ctrlName As String = String.Empty
        If Prefix = "" Then Prefix = String.Empty 'simply to read better later


        adptr = New DL.DatabaseSpecific.DataAccessAdapter
        adptr.FetchEntity(objEntity)
        adptr.CloseConnection()

        Try
            For Each control In grpBox.Controls
                If (control.HasChildren) Then
                    For Each childControl In control.Controls
                        ctrlName = childControl.Name
                        'check against custom names if not and has name has prefix, fix name
                        If Not (Prefix = String.Empty) And Not (isCustomName(ctrlName, CustNames)) Then stripPrefix(Prefix, ctrlName)
                        Select Case childControl.GetType.ToString
                            Case "System.Windows.Forms.Label"
                                'do data work here
                                If (IsNameMapped(ctrlName, objEntity)) Then
                                    childControl.Text = objEntity.Fields(ctrlName).CurrentValue.ToString
                                ElseIf isCustomName(ctrlName, CustNames) Then
                                    childControl.Text = objEntity.Fields(ctrlName).CurrentValue.ToString
                                End If
                            Case "System.Windows.Forms.TextBox"
                                'do data work here
                                If (IsNameMapped(ctrlName, objEntity)) Then
                                    childControl.Text = objEntity.Fields(ctrlName).CurrentValue.ToString
                                ElseIf isCustomName(ctrlName, CustNames) Then
                                    childControl.Text = objEntity.Fields(ctrlName).CurrentValue.ToString
                                End If
                            Case "System.Windows.Forms.ComboBox"
                                tmpDrpDown = childControl
                                'do data work here
                                If (IsNameMapped(ctrlName, objEntity)) Then
                                    tmpDrpDown.SelectedValue = objEntity.Fields(ctrlName).CurrentValue.ToString
                                ElseIf isCustomName(ctrlName, CustNames) Then
                                    tmpDrpDown.SelectedValue = objEntity.Fields(ctrlName).CurrentValue.ToString
                                End If
                            Case "System.Windows.Forms.DateTimePicker"
                                tmpCalendar = childControl
                                'do data work here
                                If (IsNameMapped(ctrlName, objEntity)) Then
                                    tmpCalendar.Value = CDate(objEntity.Fields(ctrlName).CurrentValue.ToString)
                                ElseIf isCustomName(ctrlName, CustNames) Then
                                    tmpCalendar.Value = CDate(objEntity.Fields(ctrlName).CurrentValue.ToString)
                                End If
                            Case "System.Windows.Forms.NumericUpDown"
                                tmpNumeric = childControl
                                'do data work hereok, 
                                If (IsNameMapped(ctrlName, objEntity)) Then
                                    tmpNumeric.Value = objEntity.Fields(ctrlName).CurrentValue
                                ElseIf isCustomName(ctrlName, CustNames) Then
                                    tmpNumeric.Value = objEntity.Fields(ctrlName).CurrentValue
                                End If
                            Case "Infragistics.Win.UltraWinGrid.UltraCombo"
                                tmpUltraCmb = childControl
                                If (IsNameMapped(ctrlName, objEntity)) Then
                                    tmpUltraCmb.Value = objEntity.Fields(ctrlName).CurrentValue
                                ElseIf isCustomName(ctrlName, CustNames) Then
                                    tmpUltraCmb.Value = objEntity.Fields(ctrlName).CurrentValue
                                End If
                            Case Else
                        End Select
                        ctrlName = String.Empty
                        tmpDrpDown = Nothing
                    Next
                Else
                    ctrlName = control.Name
                    If Not (Prefix = String.Empty) Then stripPrefix(Prefix, ctrlName)
                    Select Case control.GetType.ToString
                        Case "System.Windows.Forms.Label"
                            'do data work here
                            If (IsNameMapped(ctrlName, objEntity)) Then
                                control.Text = objEntity.Fields(ctrlName).CurrentValue.ToString
                            ElseIf isCustomName(ctrlName, CustNames) Then
                                control.Text = objEntity.Fields(ctrlName).CurrentValue.ToString
                            End If
                        Case "System.Windows.Forms.TextBox"
                            'do data work here
                            If (IsNameMapped(ctrlName, objEntity)) Then
                                control.Text = objEntity.Fields(ctrlName).CurrentValue.ToString
                            ElseIf isCustomName(ctrlName, CustNames) Then
                                control.Text = objEntity.Fields(ctrlName).CurrentValue.ToString
                            End If
                        Case "System.Windows.Forms.ComboBox"
                            tmpDrpDown = control
                            'do data work here
                            If (IsNameMapped(ctrlName, objEntity)) Then
                                objEntity.SetNewFieldValue(ctrlName, tmpDrpDown.SelectedValue)
                            ElseIf isCustomName(ctrlName, CustNames) Then
                                objEntity.SetNewFieldValue(ctrlName, tmpDrpDown.SelectedValue)
                            End If
                        Case "System.Windows.Forms.DateTimePicker"
                            tmpCalendar = control
                            'do data work here
                            If (IsNameMapped(ctrlName, objEntity)) Then
                                tmpCalendar.Value = CDate(objEntity.Fields(ctrlName).CurrentValue.ToString)
                            ElseIf isCustomName(ctrlName, CustNames) Then
                                tmpCalendar.Value = CDate(objEntity.Fields(ctrlName).CurrentValue.ToString)
                            End If
                        Case "System.Windows.Forms.NumericUpDown"
                            tmpNumeric = control
                            'do data work here 
                            If (IsNameMapped(ctrlName, objEntity)) Then
                                tmpNumeric.Value = objEntity.Fields(ctrlName).CurrentValue
                            ElseIf isCustomName(ctrlName, CustNames) Then
                                tmpNumeric.Value = objEntity.Fields(ctrlName).CurrentValue
                            End If
                        Case "Infragistics.Win.UltraWinGrid.UltraCombo"
                            tmpUltraCmb = control
                            If (IsNameMapped(ctrlName, objEntity)) Then
                                tmpUltraCmb.Value = objEntity.Fields(ctrlName).CurrentValue
                            ElseIf isCustomName(ctrlName, CustNames) Then
                                tmpUltraCmb.Value = objEntity.Fields(ctrlName).CurrentValue
                            End If
                    End Select
                    ctrlName = String.Empty
                End If
            Next



            Return String.Empty
        Catch ex As Exception
            Return ex.ToString
        End Try

    End Function

'--- save functions
 Public Function saveProjectObj(ByRef frm As Form, ByRef objEntity As EntityBase2, ByRef CustNames As Dictionary(Of String, String), ByVal isNew As Boolean) As String
        'Data object
        'Dim Prj As New DL.EntityClasses.ProjectEntity
        Dim adptr As DL.DatabaseSpecific.DataAccessAdapter

        'Windows Form Controls
        Dim control As System.Windows.Forms.Control
        Dim childControl As System.Windows.Forms.Control
        Dim tmpDrpDown As System.Windows.Forms.ComboBox
        Dim tmpCalendar As System.Windows.Forms.DateTimePicker
        Dim tmpNumeric As System.Windows.Forms.NumericUpDown
        Dim ctrlName As String = String.Empty
        Dim tmpUltraCmb As Infragistics.Win.UltraWinGrid.UltraCombo

        Try
            For Each control In frm.Controls
                If (control.HasChildren) Then
                    For Each childControl In control.Controls
                        ctrlName = childControl.Name
                        Select Case childControl.GetType.ToString
                            Case "System.Windows.Forms.TextBox"
                                'do data work here
                                If (IsNameMapped(ctrlName, objEntity)) Then
                                    objEntity.SetNewFieldValue(ctrlName, childControl.Text)
                                ElseIf isCustomName(ctrlName, CustNames) Then
                                    objEntity.SetNewFieldValue(ctrlName, childControl.Text)
                                End If
                            Case "System.Windows.Forms.ComboBox"
                                tmpDrpDown = childControl
                                'do data work here
                                If (IsNameMapped(ctrlName, objEntity)) Then
                                    objEntity.SetNewFieldValue(ctrlName, tmpDrpDown.SelectedValue)
                                ElseIf isCustomName(ctrlName, CustNames) Then
                                    objEntity.SetNewFieldValue(ctrlName, tmpDrpDown.SelectedValue)
                                End If
                            Case "System.Windows.Forms.DateTimePicker"
                                tmpCalendar = childControl
                                'do data work here
                                If (IsNameMapped(ctrlName, objEntity)) Then
                                    objEntity.SetNewFieldValue(ctrlName, tmpCalendar.Value.Date)
                                ElseIf isCustomName(ctrlName, CustNames) Then
                                    objEntity.SetNewFieldValue(ctrlName, tmpCalendar.Value.Date)
                                End If
                            Case "System.Windows.Forms.NumericUpDown"
                                tmpNumeric = childControl
                                'do data work hereok, 
                                If (IsNameMapped(ctrlName, objEntity)) Then
                                    objEntity.SetNewFieldValue(ctrlName, tmpNumeric.Value)
                                ElseIf isCustomName(ctrlName, CustNames) Then
                                    objEntity.SetNewFieldValue(ctrlName, tmpNumeric.Value)
                                End If
                            Case "Infragistics.Win.UltraWinGrid.UltraCombo"
                                tmpUltraCmb = childControl
                                If (IsNameMapped(ctrlName, objEntity)) Then
                                    objEntity.SetNewFieldValue(ctrlName, tmpUltraCmb.Value)
                                ElseIf isCustomName(ctrlName, CustNames) Then
                                    objEntity.SetNewFieldValue(ctrlName, tmpUltraCmb.Value)
                                End If
                            Case Else

                        End Select
                        ctrlName = String.Empty
                        tmpDrpDown = Nothing
                    Next
                Else
                    ctrlName = control.Name
                    Select Case control.GetType.ToString
                        Case "System.Windows.Forms.TextBox"
                            'do data work here
                            If (IsNameMapped(ctrlName, objEntity)) Then
                                objEntity.SetNewFieldValue(ctrlName, control.Text)
                            ElseIf isCustomName(ctrlName, CustNames) Then
                                objEntity.SetNewFieldValue(ctrlName, control.Text)
                            End If
                        Case "System.Windows.Forms.ComboBox"
                            tmpDrpDown = control
                            'do data work here
                            If (IsNameMapped(ctrlName, objEntity)) Then
                                objEntity.SetNewFieldValue(ctrlName, tmpDrpDown.SelectedValue)
                            ElseIf isCustomName(ctrlName, CustNames) Then
                                objEntity.SetNewFieldValue(ctrlName, tmpDrpDown.SelectedValue)
                            End If
                        Case "System.Windows.Forms.DateTimePicker"
                            tmpCalendar = control
                            'do data work here
                            If (IsNameMapped(ctrlName, objEntity)) Then
                                objEntity.SetNewFieldValue(ctrlName, tmpCalendar.Value.Date)
                            ElseIf isCustomName(ctrlName, CustNames) Then
                                objEntity.SetNewFieldValue(ctrlName, tmpCalendar.Value.Date)
                            End If
                        Case "System.Windows.Forms.NumericUpDown"
                            tmpNumeric = control
                            'do data work here 
                            If (IsNameMapped(ctrlName, objEntity)) Then
                                objEntity.SetNewFieldValue(ctrlName, tmpNumeric.Value)
                            ElseIf isCustomName(ctrlName, CustNames) Then
                                objEntity.SetNewFieldValue(ctrlName, tmpNumeric.Value)
                            End If
                        Case "Infragistics.Win.UltraWinGrid.UltraCombo"
                            tmpUltraCmb = control
                            If (IsNameMapped(ctrlName, objEntity)) Then
                                objEntity.SetNewFieldValue(ctrlName, tmpUltraCmb.Value)
                            ElseIf isCustomName(ctrlName, CustNames) Then
                                objEntity.SetNewFieldValue(ctrlName, tmpUltraCmb.Value)
                            End If
                    End Select
                    ctrlName = String.Empty
                End If
            Next


            objEntity.IsNew = isNew
            adptr = New DL.DatabaseSpecific.DataAccessAdapter
            adptr.SaveEntity(objEntity)
            adptr.CloseConnection()

            Return String.Empty
        Catch ex As Exception
            Return ex.ToString
        End Try

    End Function

    '--helper data functions
    Private Function IsNameMapped(ByRef ColName As String, ByRef objEntity As SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2) As Boolean
        Dim isValue As Boolean = False
        Dim x As Byte

        For x = 0 To objEntity.Fields.Count - 1
            If objEntity.Fields(x).Name = ColName Then
                isValue = True
                Return isValue
                Exit For
            End If
        Next
        Return isValue

    End Function

    Private Function isCustomName(ByRef CtrlName As String, ByRef CustNames As Dictionary(Of String, String)) As Boolean

        If IsNothing(CustNames) Then Return False

        ' Iterate through a dictionary
        For Each key As String In CustNames.Keys
            If key = CtrlName Then
                CtrlName = CustNames.Item(key).ToString
                Return True
            End If
        Next
        Return False
    End Function

    Private Sub stripPrefix(ByVal PreFix As String, ByRef NameToStrip As String)
        Dim tmpStr As String = String.Empty
        tmpStr = NameToStrip.Replace(PreFix, "")
        NameToStrip = tmpStr
    End Sub

vzwMann
User
Posts: 6
Joined: 28-Mar-2007
# Posted on: 20-Apr-2007 18:50:39   

PS---> If you are using this in a class here are your imports

'Datalayer Objs Imports YourRoot.DL.DatabaseSpecific Imports YourRoot.DL.EntityClasses Imports YourRoot.DL.FactoryClasses Imports YourRoot.DL.HelperClasses Imports YourRoot.DL.RelationClasses Imports YourRoot 'Windows Forms Imports SD.LLBLGen.Pro.ORMSupportClasses Imports System.Windows.Forms.Control Imports System.Windows.Forms

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 22-Apr-2007 14:50:31   

Thanks for your sharing your code example ! smile

Frans Bouma | Lead developer LLBLGen Pro