I've just answered a question over here where I said that there is no functional difference between
{Binding TargetProperty}
and
{Binding Path=TargetProperty}
and, as far as I'm aware what I have written is fundamentally correct. However the idea that one will use the constructor and the other sets the property got me thinking that there could be a difference, so I whipped open reflector and had a look.
The constructor has the following code in it:
public Binding(string path)
{
this._source = UnsetSource;
if (path != null)
{
if (Dispatcher.CurrentDispatcher == null)
{
throw new InvalidOperationException();
}
this._ppath = new PropertyPath(path, new object[0]);
this._attachedPropertiesInPath = -1;
}
}
The path property is this:
public PropertyPath Path
{
get
{
return this._ppath;
}
set
{
base.CheckSealed();
this._ppath = value;
this._attachedPropertiesInPath = -1;
base.ClearFlag(BindingBase.BindingFlags.PathGeneratedInternally);
}
}
So when you set the path through the property the PathGeneratedInternally flag is cleared. Now, this flag isn't exposed anywhere publicly directly, but it does seem to be used in a few places:
internal void UsePath(PropertyPath path)
{
th开发者_如何学Gois._ppath = path;
base.SetFlag(BindingBase.BindingFlags.PathGeneratedInternally);
}
[EditorBrowsable(EditorBrowsableState.Never)]
public bool ShouldSerializePath()
{
return ((this._ppath != null) && !base.TestFlag(BindingBase.BindingFlags.PathGeneratedInternally));
}
I'm sure it's all fairly inconsequential, but does anyone out there know what this flag means and why it maybe different depending on how you declare the binding?
The key is to see where the UsePath method is referenced from. By default the flag won't be set, so clearing it is basically a no-op. There is no reason to clear it in the constructor, because you know it hasn't been set in that case (because the object is still being constructed).
The UsePath method is only called in one location and that's the ClrBindingWorker constructor. If you look in there you will see they automatically create a "blank" or "empty" path and pass that to UsePath.
I suspect they do this so the Path is "valid" when used internally, even if it just refers to the binding source (which is the default behavior when no path is given). If you later set the Path property on the Binding, the flag that indicates the Path was automatically generated must be cleared.
精彩评论