BrokenRules Sample for root and children like Visual StudioBrokenRules Sample for root and children like Visual Studio
Old forum URL: forums.lhotka.net/forums/t/4454.aspx
JohnB posted on Monday, March 03, 2008
You can take this sample app and do with it what you want. This is my way of giving something back to the group.
Disclaimer: There are many ways to do what I did. It is certainly not meant to be perfect but just one of many ways to 'skin the cat'.
Application Structure: Csla 3.0.3, VS2005, no database required. I spiced it up a little using the WeifenLuo panels. You should only need to update your Csla reference path.
BrokenRulesSample Application
1) MainForm - The main form for the application and also the container for the message panel what we will use to display broken rules to the user.
2) MessagePanel - Used to display broken rules to the user as they occur with changes made to the data.
3) ContentEdit - Where all the data editing takes place. All user interaction.
4) BaseForm - All ContentEdit forms would inherit from the base form. The reason I did this was so that I could 'hide' the broken rules plumbing from the developer. Nothing gets missed this way...
5) BrokenRulesCollectionHelper - Used to retrieve the broken rules collections from the Csla objects. Read the docs inside the file for more information and many props to Andrés (Xal on the forum) for his work here.
SampleLib
1) SubClassClsa - Again, nothing more than the standard subclassing of Csla with the addition of a few files.
MyBrokenRulesCollection - Esentially a subclass of the Csla BrokenRulesCollection class. Again, read the notes inside the file for more details.
MyBrokenRule - Subclass of Csla BrokenRule.
BrokenRulesChangedEventArgs - Used for custom event to pass around broken rules collection for refreshing or initing.
2) Customer (BB), Addresses (BLB), Address (BB). Standard Csla business objects. Nothing fancy, no database required.
3) CslaTypeHelper - Again, many thanks to Andrés for his work.
Hopefully this little project will help someone out as much as the help I have received here. I figure this is the least that I can do given how much Rocky has given us.
Please feel free to ask any questions, comments, likes, dislikes, bugs I have missed or whatever! I take criticism well!
JohnJohnB replied on Tuesday, March 04, 2008
Someone let me know that I forgot to include the assembly for the panels. I did a build and uploaded again. Total download is 4meg.
John
JoeFallon1 replied on Wednesday, March 05, 2008
John,
I just downloaded it and ran through it quickly.
1. Very nice job.
2. Good of you to give Andres credit so prominently in the code.
It was not immediately clear that the buttons in the panel were clickable filters that allow you to see only those errors that apply to the ones that are selected. It is a nice touch though.
In VS 2005 I could not open the ContentEdit.vb [Design] file. I cannot see the form where you lay out all the controls. I get this error:
One or more errors encountered while loading the designer. The errors are listed below. Some errors can be fixed by rebuilding your project, while others may require code changes. |
Error HRESULT E_FAIL has been returned from a call to a COM component.
If I close the Message Panel there is no way to re-open it.
In Public Module BrokenRulesCollectionHelper
Private Sub LoadPropertyData(ByVal objectType As Type)
The code loops until pCurrentType Is Nothing
The test inside the loop is for IsBusinessBase. It seems that the loop should stop once IsBusinessBase is True. I thought it continued working its way up the inheritance chain past BusinessBase. (I only looked once and could be mistaken though.)
Joe
|
JohnB replied on Wednesday, March 05, 2008
JoeFallon1: In VS 2005 I could not open the ContentEdit.vb [Design] file. I cannot see the form where you lay out all the controls.
Try rebuilding the project. That should fix your issues. There is nothing special in the form.
JoeFallon1: If I close the Message Panel there is no way to re-open it.
You need to restart the application. My intention was that this was a demo and I did not bother to wire that part up. I can added it though.
JoeFallon1: The test inside the loop is for IsBusinessBase. It seems that the loop should stop once IsBusinessBase is True.
It will continue. Notice the recursive call to the InitializeBrokenRules method again.
For Each pMethodInfo As MethodInfo In _propertyData.Item(pType)
Dim pChildObjectInfo As Object
pChildObjectInfo = pMethodInfo.Invoke(businessObject, Nothing)
If pChildObjectInfo Is Nothing Then Exit For
InitializeBrokenRules(editForm, pChildObjectInfo, False)
Next
Other than that, thanks! I hope others find it useful.
JohnB replied on Friday, March 07, 2008
Just wanted to provide an update. I modified the project to also include grandchild objects. Check it out from the link on the first post.
Thanks,
John
alef replied on Friday, March 07, 2008
On the codeplex site they have created something similar. It is called ErrorTreeView.
There is not much explanation of it, but they have created a nice example.
You can download it from:
http://www.codeplex.com/CSLAcontrib/SourceControl/ListDownloadableCommits.aspx
You have to extract the file because there is more in it.
They have created a treeview. So in the treeview you see a visual representation of root, children and grandchildren. By clicking on the error you arrive at the control where you can fix the problem.
JohnB replied on Friday, March 07, 2008
Alef,
Thanks for the information. I actually used some of the code from Xal's project, so now we have two examples of how to do this.
The more examples we have the better it is for the community.
John
JohnB replied on Monday, March 10, 2008
Just curious if anyone had any other examples or comments to share about this topic?
Thanks
xal replied on Monday, March 10, 2008
Hey John!
It looks great!! I'm glad you could reuse some of my code.
It's been a while since I've been around the forum, as you may realize. But I'm trying to catch up. I've been quite busy (and still am).
Again: great work!
Andrés
snakebyteme replied on Wednesday, February 03, 2010
Here is a simpler approach that will not recurse forever if you have grandchildren that are the same type as the Parent:
Imports Csla
Imports System.Reflection
Imports System.ComponentModel
Imports System.Text
Public Class BrokenRulesExtractor
Private mBrokenRules As List(Of Csla.Validation.BrokenRule)
Public ReadOnly Property BrokenRulesCollection() As List(Of Csla.Validation.BrokenRule)
Get
Return mBrokenRules
End Get
End Property
Public Sub GetBrokenRules(ByVal target As Object)
Dim inspectedObjects As New Collections.Generic.List(Of String)
mBrokenRules = New List(Of Csla.Validation.BrokenRule)
GetBrokenRules(target, inspectedObjects)
End Sub
Private Sub GetBrokenRules(ByVal target As Object, ByVal inspectedObjects As Collections.Generic.List(Of String))
Dim returnValue As New StringBuilder
Dim targetID As String = String.Empty
If target IsNot Nothing Then
targetID = target.GetType.ToString & ":" & target.GetHashCode().ToString
End If
If target IsNot Nothing AndAlso Not inspectedObjects.Contains(targetID) Then
inspectedObjects.Add(targetID)
Dim myType As Type = target.GetType
If myType.BaseType.Name.Contains("BusinessListBase") Then
If target.IsDirty Then
' check error messages for each row in the list
For oneItem As Integer = 0 To CType(target, IBindingList).Count - 1
If TypeOf CType(target, IBindingList)(oneItem) Is Csla.Core.BusinessBase Then
GetBrokenRules(CType(target, IBindingList)(oneItem), inspectedObjects)
End If
Next
End If
Else
If TypeOf target Is Csla.Core.BusinessBase Then
If target.IsDirty Then
' run through broken rules collection for this object
For Each oneBrokenRule As Csla.Validation.BrokenRule In CType(target, Csla.Core.BusinessBase).BrokenRulesCollection
' if we do not have this message already, add it
If Not mBrokenRules.Contains(oneBrokenRule) Then
mBrokenRules.Add(oneBrokenRule)
End If
Next
' get list of properties for this object
Dim properties() As System.Reflection.PropertyInfo = target.GetType.GetProperties()
For Each oneProperty As System.Reflection.PropertyInfo In properties
' get object that sits on this property
If Not oneProperty.PropertyType.IsPrimitive AndAlso oneProperty.GetIndexParameters().Length = 0 Then
Dim propTarget As Object = oneProperty.GetValue(target, Nothing)
' call this procedure resursively to get error for property based object
GetBrokenRules(propTarget, inspectedObjects)
' if we do not have this message already, add it
End If
Next
End If
End If
End If
End If
End Sub
End Class
Copyright (c) Marimer LLC