Прикрепленный метод с параметрами

Если вы знаете, что такое прикрепленное свойство, то представьте себе случай, когда вам нужно предоставить 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);
    }
}

Обратите внимание, что это просто основная идея, так что это действительно первоначальный черновик, и он не предназначен для автоматического соответствия любому конкретному контексту...

Другие вопросы по тегам