Multibinding for attached property - wpf

In WPF you can use MultiBinding for normal properties. E.g.:
<TextBlock>
<TextBlock.Text>
<MultiBinding>
...
</MultiBinding>
</TextBlock.Text>
</TextBlock>
How would you do this for an attached property like Canvas.Left?

You can directly do that inline like this:
<TextBlock>
<Canvas.Left>
<MultiBinding>
<Binding Path="ABC"/>
<Binding Path="DEF"/>
</MultiBinding>
</Canvas.Left>
</TextBlock>

Related

Using a x:Static with MultiBinding

How can I use x:Static with a multi binding as below?
<TextBlock.Text>
<MultiBinding StringFormat="{x:Static language:Resource.Message} : {0}">
<Binding Path="NoOfMessages" />
</MultiBinding>
</TextBlock.Text>
There is an error yelling at me with this code.
use multiple inlines:
<TextBlock>
<Run Text="{x:Static language:Resource.Message}"/>
<Run Text=":"/>
<Run Text="{Binding NoOfMessages, Mode=OneWay}"/>
</TextBlock>
As an alternative if you want to rely on MultiBinding and StringFormat:
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} : {1}">
<Binding Source="{x:Static language:Resource.Message}"/>
<Binding Path="NoOfMessages" />
</MultiBinding>
</TextBlock.Text>
Make sure to use the escape sequence {} for the braces.

Binding Combobox does not work when a Converter is used

I'm trying to bind a ComboBox to DataContext.
<ComboBox ItemsSource="{Binding Path=Numbers}"
SelectedValue="{Binding Path=CurrentNumber,Mode=TwoWay}">
</ComboBox>
The above code works, but when I try to change how the items are displayed using a converter implementing IMultiValueConverter and MultiBinding nothing is displayed. I have debugged the method implementing the IMultiValueConverter and it is not getting executed. What could be the problem?
<ComboBox ItemsSource="{Binding Path=Numbers}"
SelectedValue="{Binding Path=CurrentNumber,Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource MultiUnitConverter}" ConverterParameter="{x:Static enumerations:Quantity.Length}" >
<Binding Path="."/>
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" Path="DataContext.CurrentUnit"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Update:
I tried the following instead of the ComboBox, the converter is fired and the data is loaded but not displayed!
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource MultiUnitConverter}" ConverterParameter="{x:Static enumerations:Quantity.Length}" >
<Binding Path="CurrentNumber"/>
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" Path="DataContext.CurrentUnit"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
The following works though:
<TextBlock>
<TextBlock.Text>
<Binding Path="CurrentNumber"></Binding>
</TextBlock.Text>
</TextBlock>
For all who may get stuck with this in the future and ruin their entire evening here is the solution I found!
It seems adding StringFormat solves the problem!
<ComboBox ItemsSource="{Binding Path=Numbers}" SelectedItem="{Binding Path=Number, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding
Converter="{StaticResource MultiUnitConverter}"
ConverterParameter="{x:Static enumerations:Quantity.Length}"
StringFormat="{}{0:0.###}">
<Binding Path="."/>
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" Path="DataContext.CurrentUnit"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Did you define the converter resource somewhere else in your xaml? If not, you should do so. For instance, if your ComboBox lives in a UserControl you could add:
<UserControl.Resources>
<local:MultiUnitConverter x:Key="multiUnitConverter"/>
</UserControl.Resources>
And of course you would need to update your Converter StaticResource to match the case-sensitive Key above.

Issue to bind more than one property into single element property

<Button>
<Button.Content>
<MultiBinding StringFormat="{}{0},{1}">
<Binding Path="Width" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}"/>
<Binding Path="Height" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}"/>
</MultiBinding>
</Button.Content>
</Button>
Here i tried to bind the window's width and height into button content but it doesn't make sense.
As Adrian suggested, you have to assign the result of a StringFormat binding to a text control. Try this instead:
<Button>
<Button.Content>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0},{1}">
<Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type Button}}"/>
<Binding Path="ActualHeight" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type Button}}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Button.Content>
</Button>
you can try something like
<Button>
<Button.Content>
<TextBlock TextAlignment="Left">
<Run Text="{Binding ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}"/>
<Run Text=" | " />
<Run Text="{Binding ActualHeight" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}"/>
</TextBlock>
</Button.Content>
</Button>
By using Run you can create whatever you want to display. and also can show on diffrent style on each Run for e.g. you can create bold effect on first run and other could be diffrent as like italic or something else.
Rether then using Height and Width properties of Window use ActualHeight and ActualWidth Properties which will provide you a actual values. there could be a chance that you will get NAN on Height and Width as they were not defined specifically.

How do I set a Multibinding and Image in Expander Header

perhaps you can help me to solve this problem. I want to display a Text-Multibinding and an image in the header of my expander.
This is my simplified coding of the expander:
<Expander
x:Name="_myExpander">
<Expander.Header>
<MultiBinding
Converter="{StaticResource ExpanderHeaderConverter}">
<Binding
Path="Property1" />
<Binding
Path="Property2" />
<Binding
Path="Property3" />
</MultiBinding>
</Expander.Header>
<local:Content/>
</Expander>
How can I set an image in there?
thanks in advance!
Try this:
<Expander.Header>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ...}"/>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource ExpanderHeaderConverter}">
<Binding Path="Property1" />
<Binding Path="Property2" />
<Binding Path="Property3" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</Expander.Header>

XAML Tool Tip Data Context and Multi Binding

I have a ListView in my XAML and I am trying to hook up a MultiBinding Converter.
<ListView
Grid.Column="4"
Grid.Row="1"
Grid.RowSpan="5"
Margin="8,0,8,8"
HorizontalAlignment="Stretch"
Name="lvDisplayType"
ItemsSource="{Binding Path=Types}"
SelectedItem="{Binding Path=Current.Opt}"
VerticalAlignment="Stretch"
SelectionChanged="lvType_SelectionChanged"
SelectionMode="Single"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel
HorizontalAlignment="Center">
<TextBlock
Text="{Binding Path=., Converter={StaticResource DisplayConverter}}"
HorizontalAlignment="Center"
Padding="6"
VerticalAlignment="Center"
TextWrapping="Wrap">
<TextBlock.ToolTip>
<ToolTip DataContext="{Binding Path=Current}">
<MultiBinding Converter="{StaticResource OptConverter}">
<Binding Path="Opt" />
<Binding Path="Type" />
</MultiBinding>
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The code not working is:
<TextBlock.ToolTip>
<ToolTip DataContext="{Binding Path=Current}">
<MultiBinding Converter="{StaticResource OptConverter}">
<Binding Path="Opt" />
<Binding Path="Type" />
</MultiBinding>
</ToolTip>
</TextBlock.ToolTip>
At present the Converter is returning an empty string as both 'values[0] == System.Windows.DependencyProperty.UnsetValue' and 'values[1] == System.Windows.DependencyProperty.UnsetValue' return true. These values are never set.
Because of the logical tree (I think) the TextBlock.ToolTip default binding is 'Current.Opt'. For the MultiBinding I also need to refer to 'Type' which is another property of 'Current'. So to get around this I have set 'ToolTip DataContext="{Binding Path=Current}"' - this isn't working as expected - what am I doing wrong?
I know I could do this easily in the Code behind, but we are employing MVVM, so would like to avoid it if possible.
Any help greatly appreciated!
Thank you
Try to do it in this way,
1.Does this give DependencyProperty.UnsetValue in the Converter? Otherwise, what is coming in to the converter?
<TextBlock.ToolTip>
<MultiBinding Converter="{StaticResource OptConverter}">
<Binding RelativeSource="{RelativeSource Self}" />
<Binding RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</TextBlock.ToolTip>
2.Does this give DependencyProperty.UnsetValue in the Converter?
<TextBlock.ToolTip>
<MultiBinding Converter="{StaticResource OptConverter}">
<Binding RelativeSource="{RelativeSource Self}" Path="Current"/>
<Binding RelativeSource="{RelativeSource Self}" Path="Current"/>
</MultiBinding>
</TextBlock.ToolTip>

Resources