Прикрепленный метод с параметрами
Если вы знаете, что такое прикрепленное свойство, то представьте себе случай, когда вам нужно предоставить 2 или более из них в целом ( здесь пример), и только если все они установлены, что-то произойдет.
Это звучит как вызов метода с параметрами для меня, поэтому ничто.
Кто-нибудь пробовал что-нибудь подобное? Я полагаю, что это также может решить мою текущую проблему с таким уродливым решением (имеющим 10x умножить на 3 свойства):
<TextBox local:DynamicBinding.Property1="{Binding IsCheckedPath}"
local:DynamicBinding.Source1="{Binding IsCheckedSource}"
local:DynamicBinding.Target1="IsChecked"
local:DynamicBinding.Property2="{Binding WidthPath}"
local:DynamicBinding.Source2="{Binding WidthSource}"
local:DynamicBinding.Target2="Width"
local:DynamicBinding.Property3="{Binding TextPath"
local:DynamicBinding.Source3="{Binding TextSource}"
local:DynamicBinding.Target3="Text" ... />
В идеале я бы хотел что-то вроде этого
<TextBox IsChecked="{Binding Path={Binding IsCheckedPath}, Source={Binding IsCheckedSource}}"
Width="{Binding Path={Binding WidthPath}, Source={Binding WidthSource}}"
Text="{Binding Path={Binding TextPath}, Source={Binding TextSource}}"
Или, может быть, даже более кратко, какие-либо идеи?
1 ответ
Итак, вместо вашего идеального связывания
Text="{Binding Path={Binding MyText}, Source={Binding MySource}}"
Я бы предложил использовать свойство switch
Text="{Binding BindingMyText}"
это может быть реализовано с помощью посетителя ViewModel (это выглядит сложнее, но сделано специально для того, чтобы сделать недопустимые состояния недопустимыми)
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");
}
}
}
и много разных модельных источников
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);
}
}
Обратите внимание, что это просто основная идея, так что это действительно первоначальный черновик, и он не предназначен для автоматического соответствия любому конкретному контексту...