CSLA .NET

Vibrant discussion about CSLA .NET and using the framework to build great business applications.

Forum has moved

New location: CSLA .NET forum


CSLA .NET Resources:
  • CSLA .NET forum
  • CSLA .NET home page
  • XAML Conditionally required Business Rules + UI warnings

    Answered (Verified) This post has 2 verified answers | 3 Replies | 1 Follower

    Top 150 Contributor
    59 Posts
    jamie.clayton posted on Sun, Apr 22 2012 4:22 AM

    G'day,

    I'm having a senior moment with XAML and CSLA business rules displaying optionally required fields in WPF at the moment. Can someone please put me out of my misery?

    I have a simple business Rule like like the following, so if a user selected the report format should be PDF, there is a conditional requirement to also supply the file path and name of file for that report.

    Private Shared Function PdfFilePathSuppliedRule(Of T As ReportDataFilter)
    (ByVal target As T, ByVal e As Validation.RuleArgsAs Boolean     Dim result As Boolean = True     If target.IsOutputToPDF Then         If String.IsNullOrWhiteSpace(target.PdfFilePath) Then             result = False             e.Description = "Must supply a location and file name 
    for the PDF report output."
            End If     End If     Return result End Function

    So the XAML UI should, in my mind do the following.

    1. User Clickes on Checkbox - Output to PDF.
    2. PDF file path text box should now highlight as a required field, with the standard red boarder.
    3. User see's red and supplies file path.
    4. Report can be generated.

    So I apply this logic and ensure that the property change also triggers the business rules to run from both properties and they are implicitly related via this business rule. The UI just never updates the conditionally required text box when the check box property changes. All the events fire as expected when I debug through this code. It looks like the UI warnings only change if the matching property changes.

    I then start to review what's going on in the CSLA core code for Csla.Wpf.PropertyStatus in (3.8.4). It implies the only way you can force the second property to display the broken rule to the user is to

    1. Force a change in the value of the PdfFilePath property and then instantly undo it.
    2. Disconnect and then reconnect the XAML framework object to the CSLA BO property.

    This all sounds a little complicated, or my reading of C# might be incorrect, usually indicating I've stuffed up somewhere.  Is there a CSLA method call I've missed, that can help me resolve this UI business rule issue in WPF?

    Jamie Clayton
    Senior Application Developer

    Website: Jenasys Design - Australia
    Blog: Practical CSLA

    Answered (Verified) Verified Answer

    Top 150 Contributor
    59 Posts
    Verified by jamie.clayton

    Did some searching in the Forum and tried a few techniques. Eventually found a solution.

    ''' <summary>
    ''' All custom rules need to be placed in this method.
    ''' </summary>
    ''' <Returns>Return true to override the generated rules If false generated rules will be run.</Returns>
    Protected Function AddBusinessValidationRules() As Boolean
     
        '   We want the UI warnings for Report outputs types, to go against the file text boxes,
        '   so we are taking the step of validating against the file path fields and associating the two properties as Dependant.
     
        '   Ensure that a PDF file path is supplied if the users selects output to pdf.           
        ValidationRules.AddRule(Of ReportDataFilter, RuleArgs)(AddressOf ReportDataFilter.PdfFilePathSuppliedRule, New RuleArgs(PdfFilePathProperty))
        ValidationRules.AddDependentProperty(IsOutputToPDFProperty, PdfFilePathProperty, True)
     
        '   Ensure that a Excel file path is supplied if the users selects output to Excel.
        ValidationRules.AddRule(Of ReportDataFilter, RuleArgs)(AddressOf ReportDataFilter.ExcelFilePathSuppliedRule, New RuleArgs(ExcelFilePathProperty))
        ValidationRules.AddDependentProperty(IsOutputToExcelProperty, ExcelFilePathProperty, True)
     
        Return False
    End Function
    ''' <summary>
    ''' We need to force cross checking of other properties as they are dependent properties together.
    ''' </summary>
    ''' <param name="propertyName"></param>
    ''' <remarks></remarks>
    Protected Overrides Sub OnPropertyChanged(ByVal propertyName As String)
        MyBase.OnPropertyChanged(propertyName)
     
        '   Fake the editing of other fields.
        '   Works in combination with the ValidationRules.AddDependentProperty
        Select Case propertyName
            Case IsOutputToPDFProperty.Name
                OnPropertyChanged(PdfFilePathProperty.Name)
            Case IsOutputToExcelProperty.Name
                OnPropertyChanged(ExcelFilePathProperty.Name)
        End Select
     
    End Sub

    Jamie Clayton
    Senior Application Developer

    Website: Jenasys Design - Australia
    Blog: Practical CSLA

    Top 10 Contributor
    2,279 Posts
    Verified by jamie.clayton

    Hi Jamie,

    You Rules is corrrect but the OnPropertyChanged override should not be required to make this work.

    I suspect that your app is using "Windows" as PropertyChangedMode.

    For XAML in CSLA 3.x you must set
    CslaPropertyChangedMode = "Xaml"
    in app.config to make your app use the XAML property changed mode.

    Windows is default mode for all Csla 3.x.
    Xaml
    is default mode for Csla 4.x

    This is the actual code in BusinessBase:

        protected virtual void PropertyHasChanged(Csla.Core.IPropertyInfo property)
        {
          MarkDirty(true);
          var propertyNames = BusinessRules.CheckRules(property);
          if (ApplicationContext.PropertyChangedMode == ApplicationContext.PropertyChangedModes.Windows)
            OnPropertyChanged(property);
          else
            foreach (var name in propertyNames)
              OnPropertyChanged(name);
        }

    So when PropertyChangedMode is Windows the <BO> will only raise OnPropertyChanged for PrimaryProperty.
    But when PropertyChangedMode is Xaml the <BO> will raise OnPropertyChanged for all AffectedProperties and this should do the same work as your OnPropertyChanged override.

    Jonny Bekkum, Norway CslaContrib Coordinator

    All Replies

    Top 150 Contributor
    59 Posts
    Verified by jamie.clayton

    Did some searching in the Forum and tried a few techniques. Eventually found a solution.

    ''' <summary>
    ''' All custom rules need to be placed in this method.
    ''' </summary>
    ''' <Returns>Return true to override the generated rules If false generated rules will be run.</Returns>
    Protected Function AddBusinessValidationRules() As Boolean
     
        '   We want the UI warnings for Report outputs types, to go against the file text boxes,
        '   so we are taking the step of validating against the file path fields and associating the two properties as Dependant.
     
        '   Ensure that a PDF file path is supplied if the users selects output to pdf.           
        ValidationRules.AddRule(Of ReportDataFilter, RuleArgs)(AddressOf ReportDataFilter.PdfFilePathSuppliedRule, New RuleArgs(PdfFilePathProperty))
        ValidationRules.AddDependentProperty(IsOutputToPDFProperty, PdfFilePathProperty, True)
     
        '   Ensure that a Excel file path is supplied if the users selects output to Excel.
        ValidationRules.AddRule(Of ReportDataFilter, RuleArgs)(AddressOf ReportDataFilter.ExcelFilePathSuppliedRule, New RuleArgs(ExcelFilePathProperty))
        ValidationRules.AddDependentProperty(IsOutputToExcelProperty, ExcelFilePathProperty, True)
     
        Return False
    End Function
    ''' <summary>
    ''' We need to force cross checking of other properties as they are dependent properties together.
    ''' </summary>
    ''' <param name="propertyName"></param>
    ''' <remarks></remarks>
    Protected Overrides Sub OnPropertyChanged(ByVal propertyName As String)
        MyBase.OnPropertyChanged(propertyName)
     
        '   Fake the editing of other fields.
        '   Works in combination with the ValidationRules.AddDependentProperty
        Select Case propertyName
            Case IsOutputToPDFProperty.Name
                OnPropertyChanged(PdfFilePathProperty.Name)
            Case IsOutputToExcelProperty.Name
                OnPropertyChanged(ExcelFilePathProperty.Name)
        End Select
     
    End Sub

    Jamie Clayton
    Senior Application Developer

    Website: Jenasys Design - Australia
    Blog: Practical CSLA

    Top 10 Contributor
    2,279 Posts
    Verified by jamie.clayton

    Hi Jamie,

    You Rules is corrrect but the OnPropertyChanged override should not be required to make this work.

    I suspect that your app is using "Windows" as PropertyChangedMode.

    For XAML in CSLA 3.x you must set
    CslaPropertyChangedMode = "Xaml"
    in app.config to make your app use the XAML property changed mode.

    Windows is default mode for all Csla 3.x.
    Xaml
    is default mode for Csla 4.x

    This is the actual code in BusinessBase:

        protected virtual void PropertyHasChanged(Csla.Core.IPropertyInfo property)
        {
          MarkDirty(true);
          var propertyNames = BusinessRules.CheckRules(property);
          if (ApplicationContext.PropertyChangedMode == ApplicationContext.PropertyChangedModes.Windows)
            OnPropertyChanged(property);
          else
            foreach (var name in propertyNames)
              OnPropertyChanged(name);
        }

    So when PropertyChangedMode is Windows the <BO> will only raise OnPropertyChanged for PrimaryProperty.
    But when PropertyChangedMode is Xaml the <BO> will raise OnPropertyChanged for all AffectedProperties and this should do the same work as your OnPropertyChanged override.

    Jonny Bekkum, Norway CslaContrib Coordinator

    Top 150 Contributor
    59 Posts

    JonnyBee:
    For XAML in CSLA 3.x you must set
    CslaPropertyChangedMode = "Xaml"
    in app.config to make your app use the XAML property changed mode

    Jonny,

    Thanks for the information on *.config settings, I wasn't aware, or forgot about page 314 of Rockies 2008 Csla book which covers this setting. This is going to be something I will need to manage as I move from a Hybrid Windows forms and WPF solution to exclusive WPF accross our customer's software. I also removed the OnPropertyChanged code and yet again your correct about not needing it.  Will be refactoring some business objects to take advantage of this knowledge, cheers!

    Jamie Clayton
    Senior Application Developer

    Website: Jenasys Design - Australia
    Blog: Practical CSLA

    Page 1 of 1 (4 items) | RSS

    Copyright (c) 2006-2014 Marimer LLC. All rights reserved.
    Email admin@lhotka.net for support.
    Powered by Community Server (Non-Commercial Edition), by Telligent Systems