View property - bind twice

2019-09-14 11:35发布

问题:

Is it possible to bind the same property of the control more than once?

To example:

<Popup IsOpen="{Binding Path=(local:ListViewBehavior.IsColumnHeaderClicked),
    RelativeSource={RelativeSource FindAncestor,  AncestorType=GridViewColumnHeader}}" ...

As you can see Popup.IsOpen is bound to attached property. I'd like to bind it to ViewModel IsPopupOpened, but have no idea how.


Trying @Arhiman answer without much success:

<Popup.IsOpen>
    <MultiBinding Converter="{local:MultiBindingConverter}">
        <Binding Path="(local:ListViewBehavior.IsColumnHeaderClicked)"
                 RelativeSource="{RelativeSource FindAncestor, AncestorType=GridViewColumnHeader}" />
        <Binding Path="DataContext.IsPopupId"
                 RelativeSource="{RelativeSource FindAncestor, AncestorType=UserControl}" />
    </MultiBinding>
</Popup.IsOpen>

Naive converter logic:

public class MultiBindingConverter : MarkupExtension, IMultiValueConverter
{
    public MultiBindingConverter() { }

    public override object ProvideValue(IServiceProvider serviceProvider) => this;

    object[] _old;

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (_old == null)
            _old = values.ToArray();
        // check if one of values is changed - that change is a new value
        for (int i = 0; i < values.Length; i++)
            if (values[i] != _old[i])
            {
                _old = values.ToArray();
                return values[i];
            }
        return values[0];
    }

    // replicate current value
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) =>
        Enumerable.Repeat(value, targetTypes.Length).ToArray();
}

回答1:

You could simply use a MultiBinding with a converter to implement the logic you'd like.

<Popup.IsOpen>
    <MultiBinding Converter="{StaticResource openLogicConverter}">
        <Binding Path="MyAttachedProperty" ... />
        <Binding Path="IsPopupOpened" />
    </MultiBinding>
</Popup.IsOpen>

I'd usually put this logic in the ViewModel, but as it is an AttachedProperty, something directly in the View seems more appropriate to me.