- Home
- LLBLGen Pro
- Architecture
Thoughts and Opinions Welcome
Joined: 29-Sep-2004
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..
Joined: 26-Feb-2006
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
Joined: 29-Sep-2004
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));
}
}
}
Joined: 28-Mar-2007
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
Joined: 28-Mar-2007
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