How do I write inline xaml for a MultiBinding converter? - c#

How do I include the second binding? Where do the brackets and commas go?
There are five thousand examples that show how to do it in xml but nothing about how this should appear inline.
NOT THIS
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0:F1}{1:F1}">
<Binding Path="A" />
<Binding Path="B" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
THIS
<StackPanel Grid.Column="0"
Orientation="Vertical"
HorizontalAlignment="Left"
Visibility="{MultiBinding Converter={StaticResource multi_bool_vis_conv},
Bindings={Binding LabelFormat.HasLotMaskShiftCode}}">
I need to pass a second binding LabelFormat.HasSomeOtherCode. How do I include that second binding?

Assuming multi_bool_vis_conv implements the interface IMultiValueConverter and you handle the different parameters by indexing off of the value array, the binding should look like this:
<MultiBinding Converter="{StaticResource YourConverter}">
<Binding Path="YourProperty1"/>
<Binding Path="YourProperty2"/>
</MultiBinding>
I assume you want this on one line ("in-line") because you want to set the binding on the StackPanel's Visiblity property and your not sure how to do that in a multi-line way...
You can break it out like this:
<StackPanel>
<StackPanel.Visibility>
<MultiBinding Converter="{StaticResource YourConverter}">
<Binding Path="YourProperty1" />
<Binding Path="YourProperty2" />
</MultiBinding>
</StackPanel.Visibility>
</StackPanel>
The only other way I can see to do what you want is to roll your own StackPanel and include dependency properties for each of the bindings you want. You can then bind each of those on their own line and forgo a binding on the Visibility property all-together, instead opting to control the visibility in the code-behind of your custom control.

Related

What is the order of setting properties in XAML?

I have a TextBlock with two properties (Text and Foreground) bound to the same ViewModel property.
Both also have converters. One of the converters checks the Text property and returns a 'dash' if the value is NaN. The other checks that the value is above, below or equals zero and accordingly sets the foreground to different colors.
XAML example:
<TextBlock>
<TextBlock.Text>
<Binding Path="AvgDistance" StringFormat="{}{0:N1}"
Converter="{x:Static converter:ValueToDash.Instance}"/>
</TextBlock.Text>
<TextBlock.Foreground>
<MultiBinding Converter="{x:Static converter:ValueToColor.Instance}">
<Binding Path="AvgDistance"/>
<Binding ElementName="currentPeriod" Path="IsChecked" />
</MultiBinding>
</TextBlock.Foreground>
</TextBlock>
Now I need that the ValueToDash converter fired before the ValueToColor converter, but it is always vice versa.
The Foreground property seems to be always set first, and only then the Text property is set.
Why is it so? And is it possible to reverse the order of setting?
You shouldn't rely on the order in which the properties are being set.
What you could do instead is to add another binding to your MultiBinding that binds to the Text property of the TextBlock:
<TextBlock>
<TextBlock.Text>
<Binding Path="AvgDistance" StringFormat="{}{0:N1}"
Converter="{x:Static converter:ValueToDash.Instance}"/>
</TextBlock.Text>
<TextBlock.Foreground>
<MultiBinding Converter="{x:Static converter:ValueToColor.Instance}">
<Binding Path="AvgDistance"/>
<Binding ElementName="currentPeriod" Path="IsChecked" />
<Binding Path="Text" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</TextBlock.Foreground>
</TextBlock>
Then the ValueToColor converter will be invoked (again) whenever the Text property is set to some new value.

Changing format xxxxxxxxxx to xxx-xxx-xxxx

I have a textbox in WPF and I need to display text in xxx-xxx-xxxx format.
<TextBox FontSize="30" Text="{Binding MyString,UpdateSourceTrigger=PropertyChanged}" Grid.Row="3" MaxLength="10"></TextBox>
MyString is just property which sets value in TextBox into it for some other logic. Can I do it in XAML itself usng StringFormat?
You can try using the MaskedTextBox to specify the format of the input.
Example:
<wpfx:MaskedTextBox Mask="000-000-0000" />
Try this tutorial also.
As an option you could split the text in the code behind (or View Model) and bind each value separately
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{0}-{1}-{2}">
<Binding Path="FirstPart" />
<Binding Path="SecondPart" />
<Binding Path="ThirdPart" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Yes you can do this. Try the following:
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}-whateverhercomes-andwhateverherecomes">
<Binding Path="MyString"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>

Using localized formatted string in WPF binding

I have a formatted string in a .resx file like so:
Blah: {0}
How do I use it in WPF binding to fill the {0} part?
i didn't tested it but...
https://social.msdn.microsoft.com/Forums/vstudio/en-US/f77ab886-2def-4cef-aed3-9ced24eb5776/using-stringformat-in-a-textblock-in-wpf?forum=wpf
so i guess you should do something like this :
<TextBlock Text="{Binding Path=MyStringParameter, StringFormat={Binding MyStringFormatResource}"/>
In addition Binding/StringFormat you can also use MultiBinding element.
<StackPanel>
<TextBox Name="countText" Text="4" />
<TextBox Name="totalText" Text="10" />
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="Select {0} of {1}">
<Binding ElementName="countText" Path="Text" />
<Binding ElementName="totalText" Path="Text" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
In a real sample you would bind something else but XAML elements but this shows you the idea.

Binding the Value of StringFormat

I have a Textbox with a Value and a Unit bound like this:
<TextBox Text="{Binding Path=Value,StringFormat='{}{0} mm'}" />
The Unit mm should be also bound to the ViewModel Property Unit. This can be done via a Multibinding:
<TextBox>
<TextBox.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="Value"
Mode="TwoWay" />
<Binding Path="Unit"
Mode="OneWay" />
</MultiBinding>
</TextBox.Text>
</TextBox>
But with this I lose my Two Way Binding and I don't want to edit the Unit aswell. If ths user deletes "8 mm" and enteres an "8" the binding should automatically reevaluate the binding and add the unit as it is done via normal string format binding.
So finally I need something like this:
<TextBox>
<TextBox.Text>
<Binding Path="Value"
StringFormat="{Binding Path=ValueUnitStringFormat}" />
</TextBox.Text>
</TextBox>
But unfortunally StringFormat Property on BindingBase is not a DependencyProperty.
Anyone got a solution for this?

Assign a converter to a member of ancestor for binding in xaml

I wanted to know how to assign my converter to a member called ConvertPoint in the ancestor Viewport?
<DataTemplate DataType="{x:Type local:TestShape}">
<DataTemplate.Resources>
<RelativeSource AncestorType="{x:Type root:Viewport}" x:Key="Viewport"/>
<root:BezierScaleConvertor x:Key="BezierScaleConvertor" />
</DataTemplate.Resources>
<control:TestShape>
<control:TestShape.StartPoint>
<MultiBinding Converter="???"> <----------- Here I don't know how to refer to the member ConvertPoint which is a convertor in Viewport, if I use dynamicResource or Binding, it will raise an exception because it's not a DP.
<Binding Path="StartPoint" />
<Binding Path="ScaleX" RelativeSource="{StaticResource Viewport}"/>
<Binding Path="ScaleY" RelativeSource="{StaticResource Viewport}" />
</MultiBinding>
</control:TestShape.StartPoint>
<control:TestShape.Segments>
<MultiBinding Converter="{StaticResource BezierScaleConvertor}">
<Binding Path="Segments" />
<Binding Path="ScaleX" RelativeSource="{StaticResource Viewport}" />
<Binding Path="ScaleY" RelativeSource="{StaticResource Viewport}" />
</MultiBinding>
</control:TestShape.Segments>
</control:TestShape>
</DataTemplate>
I finally got it out.
To 100% make this cas works, you should use c# code version of datatemplate.
That's all.

Categories

Resources