ContextBound object. If you create a class that extends context bound object and you create a ContextAttribute you can intercept the calls made to such a property and set the IsDirty. .NET will create a proxy to your class so all calls go over something like a remoting sink.
The problem with such an approach though is that your proxy will only be invoked when called externally. I'll give you an example.
class A
{
[Foo]
public int Property1{get; set;}
public int Property2{get {return variable;} set{ Property1 = value; variable = value; }
}
When property1 is called from another class, your proxy would be invoked. But if another class calls property2, even though the set of property2 will call into property1 no proxy will be invoked, (a proxy isn't necessary when you're in the class itself).
There is a lot of sample code out there of using ContextBoundObjects, look into it.