Установить множественную привязку для элемента xaml в исходном коде

#c# #wpf #xaml #data-binding #properties

#c# #wpf #xaml #привязка данных #свойства

Вопрос:

У меня есть следующий рабочий XAML-код, который в основном связывает пару свойств для вычисления конечной позиции моего пользовательского элемента управления:

 <UserControl x:Class="CurvePointControl"
    ....
         >
<UserControl.Resources>
    <local:VToYConverter x:Key="vToYConverter" />
</UserControl.Resources>
<UserControl.RenderTransform>
    <TranslateTransform x:Name="XTranslateTransform" >
        <TranslateTransform.Y>
            <MultiBinding Converter="{StaticResource vToYConverter}">
                <Binding ElementName="curveEditPoint" Path="V"/>
                <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:CurveEditor}}" Path="MinV"/>
                <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:CurveEditor}}" Path="MaxV"/>
                <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:CurveEditor}}" Path="ActualHeight"/>                    
            </MultiBinding>
        </TranslateTransform.Y>
    </TranslateTransform>
</UserControl.RenderTransform>
  

По разным причинам (но особенно, чтобы избежать относительного источника, я сейчас безуспешно пытаюсь сделать то же самое в исходном коде.

Это мой текущий код:

     public CurvePointControl(CurveEditor CV)
    {
        InitializeComponent();

        MultiBinding multiBinding = new MultiBinding();
        multiBinding.Converter = m_VToYConverter;

        multiBinding.Bindings.Add(new Binding("V"));
        multiBinding.Bindings.Add(new Binding(CV.MinVProperty)); // doesn't work
        multiBinding.Bindings.Add(new Binding(CV.MaxVProperty)); // doesn't work
        multiBinding.Bindings.Add(new Binding(CV.ActualHeight)); // doesn't work       
        multiBinding.NotifyOnSourceUpdated= true;

        this.SetBinding(TranslateTransform.YProperty, multiBinding);
        //Doesn't work too:
        //BindingOperations.SetBinding(XTranslateTransform, TranslateTransform.YProperty, multiBinding);

    }
  

Я все еще не могу поверить, что так сложно преобразовать XAML в код c #. Конвертер вызывается, но только один раз и без допустимых значений свойств.

Есть идеи, что не так? Как я мог бы отладить такую проблему?

Ответ №1:

Вам нужны исходные тексты:

 multiBinding.Bindings.Add(new Binding("V") { Source = curveEditPoint }); //If that object is accessible in the current scope.
multiBinding.Bindings.Add(new Binding("MinV") { Source = CV });
multiBinding.Bindings.Add(new Binding("MaxV") { Source = CV });
multiBinding.Bindings.Add(new Binding("ActualHeight") { Source = CV });
  

Комментарии:

1. Теперь работает нормально. Я боролся с этой проблемой в течение нескольких часов. Просто удивительно, сколько людей готовы поделиться своим опытом в Stackoverflow.

Ответ №2:

Буквальный перевод был бы:

 MultiBinding multiBinding = new MultiBinding();
multiBinding.Converter = m_VToYConverter;

RelativeSource relativeSource = new RelativeSource() { AncestorType = typeof(CurveEditor) };

multiBinding.Bindings.Add(new Binding("V") { ElementName = "curveEditPoint" });
multiBinding.Bindings.Add(new Binding(CV.MinVProperty) { RelativeSource = relativeSource });
multiBinding.Bindings.Add(new Binding(CV.MaxVProperty) { RelativeSource = relativeSource });
multiBinding.Bindings.Add(new Binding(CV.ActualHeight) { RelativeSource = relativeSource });
  

Но вы можете столкнуться с проблемами с корректным решением имени элемента. В этом случае вам пришлось бы привязываться непосредственно к элементу или «находить» его. Что-то подобное будет работать, если curveEditPoint является полем в текущем классе:

 multiBinding.Bindings.Add(new Binding("V") { Source = this.curveEditPoint });
  

Комментарии:

1. Хотя этот ответ действительно полезен в качестве будущей ссылки, это не совсем то, к чему я стремился, потому что я пытался избежать относительных привязок. Я надеюсь, что относительная привязка будет отвечать за огромное время, необходимое для создания пользовательских элементов управления (которое составляет 10 мс на элемент). Создание экземпляров на c # вместо XAML сэкономило всего 10%.

2. @pixtur — А, без проблем. Я пропустил эту часть вашего вопроса.

Ответ №3:

Попробуйте использовать

 multiBinding.Bindings.Add(new Binding("MinVProperty") { ElementName = CV.Name });
  

вместо

 multiBinding.Bindings.Add(new Binding("CV.MinVProperty"));