Set multibinding for a xaml element in code behind

10,752

Solution 1

You need sources:

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 });

Solution 2

The literal translation would be:

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 });

But you may run into problems with the ElementName resolving correctly. In that case you'd have to bind directly to the element or "find" it. Something like this would work if curveEditPoint is a field in the current class:

multiBinding.Bindings.Add(new Binding("V") { Source = this.curveEditPoint });
Share:
10,752
pixtur
Author by

pixtur

Designer and spare time developer.

Updated on June 14, 2022

Comments

  • pixtur
    pixtur almost 2 years

    I have the following working XAML code that basically binds a couple of properties to calculate the final position of my user control:

    <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>
    

    ...

    For various reasons (but esp to avoid the relative source, I am now trying to do the same in code behind without success.

    This is my current code:

        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);
    
        }
    

    I still can't believe that it is so hard to convert the XAML into c# code. The converter is called but only once and without valid property values.

    Any idea of what's wrong? How could I debug such a problem?

  • pixtur
    pixtur about 13 years
    Working nicely now. I have been struggling with this problem for several hours. It's just amazing how many people are willing to share their expertise on Stackoverflow.
  • pixtur
    pixtur about 13 years
    Although this answer is really useful as future reference, it's not really what I've been after, because I tried to avoid the relative bindings. I hope that the relative binding would be responsible for the huge time it takes to create the UserControls (which is 10ms per element). Creating the instances in c# instead of XAML saved only 10%.
  • CodeNaked
    CodeNaked about 13 years
    @pixtur - Ah, no problem. I missed that part of your question.