25

Is there a way to take this multibinding:

<TextBox.IsEnabled>
    <MultiBinding Converter="{StaticResource LogicConverter}">
        <Binding ElementName="prog0_used" Path="IsEnabled" />
        <Binding ElementName="prog0_used" Path="IsChecked" />
    </MultiBinding>
</TextBox.IsEnabled>

and put is all on one line, as in <TextBox IsEnabled="" />?

If so, where can I learn the rules of this formattiong?

Adam S
  • 8,945
  • 17
  • 67
  • 103

4 Answers4

23

A better (and simpler) approach would be to define a style as a resource which you can easily apply to any TextBox:

<Window.Resources>
    <c:MyLogicConverter x:Key="LogicConverter" />

    <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}" x:Key="MultiBound">
        <Setter Property="IsEnabled">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource LogicConverter}">
                    <Binding ElementName="switch" Path="IsEnabled" />
                    <Binding ElementName="switch" Path="IsChecked" />
                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<StackPanel Orientation="Horizontal">
    <CheckBox Name="switch" />
    <TextBox Name="textBox2" Text="Test" Style="{StaticResource MultiBound}" />
</StackPanel>
hemp
  • 5,602
  • 29
  • 43
8

This can be done with a custom markup extension:

public class MultiBinding : System.Windows.Data.MultiBinding
{
    public MultiBinding (BindingBase b1, BindingBase b2)
    {
        Bindings.Add(b1);
        Bindings.Add(b2);
    }

    public MultiBinding (BindingBase b1, BindingBase b2, BindingBase b3)
    {
        Bindings.Add(b1);
        Bindings.Add(b2);
        Bindings.Add(b3);
    }

    // Add more constructors if you need.
}

Usage:

<TextBox IsEnabled="{local:MultiBinding
    {Binding IsEnabled, ElementName=prog0_used},
    {Binding IsChecked, ElementName=prog0_used},
    Converter={StaticResource LogicConverter}}">
Athari
  • 33,702
  • 16
  • 105
  • 146
  • Removed comment and created a new answer. – Christian Myksvoll Jun 23 '15 at 05:24
  • Can be done with one constructor using the params keyword: `public MultiBinding (params BindingBase[] bindings)` – BalintPogatsa Apr 28 '19 at 19:14
  • This is a great solution! And gets around the xaml issues of the built in Multibinding. Thanks for this – mike gold Oct 30 '20 at 23:39
  • [@BalintPogatsa](https://stackoverflow.com/users/1471878/balintpogatsa) That was my first thought as well, but the `params` keyword doesn't appear to work here - compilation fails with **`error MC3009: Cannot find a public constructor for 'MultiBinding' that takes 2 arguments.`**. Have you gotten it to work with this method; and if so, how? – radj307 May 15 '22 at 18:55
4

For MultiBinding there is no shorthand string. You need to use the expanded element syntax.

John Bowen
  • 24,213
  • 4
  • 58
  • 56
4

I tried using Discord's answer, but it didn't work right out of the box. To make it work I added a new constructor:

public class MultiBinding : System.Windows.Data.MultiBinding
{
    public MultiBinding(BindingBase b1, BindingBase b2, object converter)
    {
        Bindings.Add(b1);
        Bindings.Add(b2);
        Converter = converter as IMultiValueConverter;
    }
}

Usage will then be like this:

    <TextBox IsEnabled="{local:MultiBinding {Binding IsEnabled, ElementName=prog0_used}, 
{Binding IsChecked, ElementName=prog0_used}, 
{StaticResource LogicConverter}}">
Christian Myksvoll
  • 634
  • 2
  • 7
  • 16
  • I'd like to accomplish this since I have so many controls that need to react to multiple booleans, but mine's not behaving: http://stackoverflow.com/questions/37057720/inline-multibinding-not-working-as-expected – Chris Fannin May 05 '16 at 20:55