Ok, so instead of your ideal binding
Text="{Binding Path={Binding MyText}, Source={Binding MySource}}"
I'd suggest to use a switch property
Text="{Binding BindingMyText}"
that could be implemented with a ViewModel visitor (it looks more complicated but it's done on purpose to make illegal states unrepresentable)
internal abstract class IPropVisitor<A>
{
internal abstract A bindingMyText(ModelA source);
internal abstract void bindingMyText(ModelA source, A val);
internal abstract A bindingMyText(ModelB source);
internal abstract void bindingMyText(ModelB source, A val);
}
internal class ViewModelVisitor : IPropVisitor<string>, INotifyPropertyChanged
{
internal ViewModelVisitor(ModelSource model)
{
modelSource = model;
BindingMyText = "Test!";
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
override internal string bindingMyText(ModelA source)
{
return source.MyTextA;
}
override internal void bindingMyText(ModelA source, string val)
{
source.MyTextA = val;
}
override internal string bindingMyText(ModelB source)
{
return source.MyTextB;
}
override internal void bindingMyText(ModelB source, string val)
{
source.MyTextB = val;
}
private ModelSource modelSource;
public ModelSource ModelSource
{
get { return modelSource; }
set
{
modelSource = value;
OnPropertyChanged("ModelSource");
OnPropertyChanged("BindingMyText");
}
}
public string BindingMyText
{
get
{
return modelSource.accept(this);
}
set
{
modelSource.accept(this, value);
OnPropertyChanged("BindingMyText");
}
}
}
and many different model sources
public abstract class ModelSource : ViewModelBase
{
abstract internal A accept<A>(IPropVisitor<A> visitor);
abstract internal void accept<A>(IPropVisitor<A> visitor, A val);
}
class ModelA : ModelSource
{
private string myTextA;
public string MyTextA
{
get { return myTextA; }
set {
myTextA = value;
OnPropertyChanged("MyTextA");
}
}
internal override A accept<A>(IPropVisitor<A> visitor)
{
return visitor.bindingMyText(this);
}
internal override void accept<A>(IPropVisitor<A> visitor, A val)
{
visitor.bindingMyText(this, val);
}
}
class ModelB : ModelSource
{
private string myTextB;
public string MyTextB
{
get { return myTextB; }
set
{
myTextB = value;
OnPropertyChanged("MyTextB");
}
}
internal override A accept<A>(IPropVisitor<A> visitor)
{
return visitor.bindingMyText(this);
}
internal override void accept<A>(IPropVisitor<A> visitor, A val)
{
visitor.bindingMyText(this, val);
}
}
Please note that this is simply the basic idea, so it is really an initial draft and it is not intended to automatically fit any specific context...