AddOutValue not refreshing UI (not invoking OnPropertyChanged?)

AddOutValue not refreshing UI (not invoking OnPropertyChanged?)

Old forum URL: forums.lhotka.net/forums/t/10135.aspx


Ranjini posted on Saturday, March 05, 2011

CSLA 4/Silverlight 4

I have a business rule on a BB object. This rule changes the property values for a handful of the BB's property. Sample property declaration –

public static PropertyInfo< double? > _latestValueInUCCProperty = RegisterProperty<double?>(p => p.LatestValueInUCC);

public double? LatestValueInUCC

{

get { return GetProperty(_latestValueInUCCProperty); }

set { LoadProperty(_latestValueInUCCProperty, value );

      OnPropertyChanged(_latestValueInUCCProperty);

    }

}

 

The reason I am using LoadProperty/OnPropertyChanged instead of SetProperty, is because I do not want these properties to ever change the IsDirty of the object but I still want them to refresh the UI.

 I have added each of the properties that the rule changes to the Affected Properties

AffectedProperties.AddRange(new List<IPropertyInfo> { … ,_latestValueInUCCProperty, ... });

 

And  in the “Execute” method of the rule , I change the property so..  

                               context.AddOutValue(_latestValueInUCCProperty,dLatestValue);

 

Everything executes fine and the property changes its value but the UI never gets refreshed (using TwoWay binding). I was able to achieve this by calling context.Target.OnUnknownPropertyChanged(); but I believe that shouldn’t be necessary. Can anyone please explain why OnPropertyChanged may not be being invoked automatically on context.AddOutValue?

 

Thanks
Ranjini

 

 

 

RockfordLhotka replied on Sunday, March 06, 2011

We have unit tests like this too, but here's a sample app that demonstrates that PropertyChanged is raised for each property in the output list from a rule:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Csla;
 
namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      var obj = new Test();
      obj.PropertyChanged += (o, e) =>
        {
          Console.WriteLine("PropertyChanged: " + e.PropertyName);
        };
      obj.Value1 = "abc";
      Console.WriteLine("value1: " + obj.Value1);
      Console.WriteLine("value2: " + obj.Value2);
      Console.ReadLine();
    }
  }
 
  [Serializable]
  public class Test : BusinessBase<Test>
  {
    public static PropertyInfo<string> Value1Property = RegisterProperty<string>(c => c.Value1);
    public string Value1
    {
      get { return GetProperty(Value1Property); }
      set { SetProperty(Value1Property, value); }
    }
 
    public static PropertyInfo<string> Value2Property = RegisterProperty<string>(c => c.Value2);
    public string Value2
    {
      get { return GetProperty(Value2Property); }
      set { SetProperty(Value2Property, value); }
    }
 
    protected override void AddBusinessRules()
    {
      base.AddBusinessRules();
      BusinessRules.AddRule(new MyRule());
    }
  }
 
  public class MyRule : Csla.Rules.BusinessRule
  {
    public MyRule()
    {
      PrimaryProperty = Test.Value1Property;
      AffectedProperties.Add(Test.Value2Property);
    }
 
    protected override void Execute(Csla.Rules.RuleContext context)
    {
      context.AddOutValue("value 1 set");
      context.AddOutValue(Test.Value2Property, "value 2 set");
    }
  }
}

The result of running this code is: 

PropertyChanged: Value1
PropertyChanged: Value2
value1: value 1 set
value2: value 2 set

This is the expected result - PropertyChanged is raised for each affected property.

Ranjini replied on Sunday, March 06, 2011

Thanks for your response.. I still am  unable to figure out what it is that I am doing different .. but I will keep looking for  it....

mesh replied on Sunday, July 03, 2011

I have the same problem. Anyone?

JonnyBee replied on Saturday, July 09, 2011

Which UI technology are you using?

What is the setting of Csla.ApplicationContext.PropertyChangedMode?

Code from Csla.Core.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);
    }

Copyright (c) Marimer LLC