2

Preamble: I am making a logging tool for our company needs. We use MVVM - pattern in our projects via Caliburn. At this moment my tool is capable of weaving compiled code via Mono.Cecil assembly and injecting call of a logging method in public properties set methods.

Fabula: Let's say, I have a class Person

 public class Person
    {
        public string Name
        {
            get { return _name; }
            set
            {
                 Logger.MyLogMethod(_name, value, "Person");
                _name = value;
            }
        }
        private string _name;
    }

and a class Logger

public static class Logger
    {
        public static void MyLogMethod(string oldvalue, string newvalue, string propertyname)
        {
        //condition to log only user changes
        }
    }

And an instance of a person has its Name property binded to textbox

   <TextBox Text="{Binding SelectedPerson.Name}"/>

And we have a button, which click calls a code, which will set new value to SelectedPerson.

So, we have two ways of setting our Person's Name property at a runtime. It's either by user typing in textbox, or a user clicking a button, therefore calling some code.

I would like to know: how to distinct these two cases. In other words - when a set method of a property is called - how to determine, if it was called by binding engine or by our code.

So far I have one approach that is doable in my opinion - to take a look at StackTrace. Not sure how to do it thought.

netaholic
  • 1,345
  • 10
  • 22

1 Answers1

0

You can make the Name property private. Then you expose a public property for binding and another for the rest of the application. You can know differentiate a call from binding from a call from somewhere else

 public class Person
    {
        string NameForOthers
        {
            get { return Name; }
            set
            {
                 Logger.MyLogMethod(_name, value, "Person name set by other place");
                Name= value;
            }
        }

        public string NameForBinding
        {
            get { return Name; }
            set
            {
                 Logger.MyLogMethod(_name, value, "Person name set by binding");
                Name= value;
            }
        }

        string Name
        {
            get { return _name; }
            set
            {
                 Logger.MyLogMethod(_name, value, "Person");
                _name = value;
            }
        }
        private string _name;
    }

Then you use it for your binding

 <TextBox Text="{Binding SelectedPerson.NameForBinding}"/>
AlexH
  • 2,650
  • 1
  • 27
  • 35
  • Thanks for suggestion, but I dont think this approach is suitable, since it involves either changing all binding or altering all viewmodels, and my colleagues won't be happy about it. I maybe might be able to do it with MCIL, but I believe its gonna be difficult – netaholic Sep 25 '15 at 15:24
  • If this method is not suitable, just have a look there http://stackoverflow.com/questions/19737351/determining-the-caller-inside-a-setter-or-setting-properties-silently – AlexH Sep 25 '15 at 15:49