How can I bind to a static value? - wpf

I have a MultiBinding, with 1 of the bindings, I want to use a static value eg. 1 or 0.33 how can I do that? also when I am at it, I want to bind to the value 1/3 = 0.33333... can I have an expression?
<!-- not correct syntax, but something like this is what I want to acheive -->
<Binding Value="1" />
UPDATE
I tried something like
<Binding Path="NonExistantValue" FallbackValue="0" />
But it fails ... in a "clean" app it works tho ...

Ah, I found the answer
<!-- in resources -->
<sys:Single x:Key="Single0">0</sys:Single>
<!-- in multibinding -->
<Binding Source="{StaticResource Single0}" />
I am abit confused as to why Single is a float, why the difference in names?

Related

Do you have to use a converter when using Multibinding in WPF?

I would like to know if there are scenarios where you can use a Multibinding without a converter - and the limitations which force us to use a converter.
In particular I am trying to bind a string to another two strings in a string.format style.
The most common area you use a MultiBinding without a converter is when you have a string format concatenating two individual values
say for example:
To format Names that have First, Last part and you want to format it based on locale
<StackPanel>
<TextBlock x:Name="firstName"
Text="John" />
<TextBlock x:Name="lastName"
Text="Wayne" />
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding ElementName="firstName"
Path="Text" />
<Binding ElementName="lastName"
Path="Text" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
You do see quite a lot of places you use a converter since using a MultiBinding your doing the same as a Binding but you have multiple source values formatted to a single result instead of single input -> single output.
You can have a Binding take a ConverterParameter to supply another input value however you have limitations like not being able to provide a runtime Bound value to it, which makes MultiBinding more appropriate for multiple inputs where you want to bind all of them.
It boils down to your use-case, If you want to provide a result based on different input types that you evaluate in a custom-way, you need a Converter(pretty much similar to Binding. Just think of the difference as 1 input bind-able value against multiple)

Using String from a dictionary in a ConverterParameter

I'm trying to use a String from a dictionary:
<?xml version="1.0" encoding="utf-8" ?>
<Dictionary EnglishName="English" CultureName="English" Culture="en-US">
...
<Value Id="ButtonSuppressFieldInformation"
ToolTip="Remove field" Name="Remove field number "/>
...
</Dictionary>
In this ConverterParamter to enable multiple langages support:
<Button>
...
<AutomationProperties.Name>
<MultiBinding
Converter="{StaticResource IndexedForAutomationId}"
ConverterParameter="{loc:Translate
Uid=ButtonSuppressFieldInformation, Default=Delete field}">
<Binding RelativeSource="{RelativeSource Self}" />
<Binding ElementName="MyContactDirectoryView"
Path="ListConditionToSearch" />
</MultiBinding >
</AutomationProperties.Name>
</Button>
But the only thing shown is the number (IndexedForAutomationId), the string does not appear.
Using a string instead of "{loc:Translate Uid=ButtonSuppressFieldInformation, Default=Delete field}" works:
<MultiBinding Converter="{StaticResource IndexedForAutomationId}"
ConverterParameter="Delete field">
Displays Delete field 0.
What is the way to use loc:Translate as a ConverterParameter?
This issue could be due to a lot of things and some more code would really help here. I would start, however, with a breakpoint on the Convert() method of the IndexedForAutomationId converter to 1) check if you get the values your are expecting from the inner bindings and 2) check if the converter itself is returning the right string from the dictionary.
Please make sure to review these guidelines about how to debug WPF bindings as well.

Silverlight: Select control based on list count

I'm bind a Telerik RadGridView to a List<MyObject> myList = new List<MyObject>. But if the myList.Count == 0 (the list is empty ;) ) I want to show another control to the user.
I know I could use some visibility converter, but I prefer achieving this in XAML.
Thank you
I think that value converters are your only choice here :)
However, I've found out that if you structure them properly, value converters are great.
Here are a couple of good tools for this:
A Generic Boolean Value Converter
Linking Multiple Value Converters in WPF and Silverlight
With these tools in mind, I would go with something like this:
<Grid>
<telerik:RadGridView ItemsSource="{Binding myList}">
<telerik:RadGridView.Visibility>
<Binding Path="myList">
<Binding.Converter>
<converters:SequentialValueConverter>
<converters:IsEmptyConverter />
<converters:BooleanToVisibilityConverter TrueValue="Collapsed" FalseValue="Visible" />
</converters:SequentialValueConverter>
</Binding.Converter>
</Binding>
</telerik:RadGridView.Visibility>
</telerik:RadGridView>
<YourControl>
<YourControl.Visibility>
<Binding Path="myList">
<Binding.Converter>
<converters:SequentialValueConverter>
<converters:IsEmptyConverter />
<converters:BooleanToVisibilityConverter TrueValue="Visible" FalseValue="Collapsed" />
</converters:SequentialValueConverter>
</Binding.Converter>
</Binding>
</YourControl.Visibility>
</YourControl>
</Grid>
Also, as Jason said, myList needs to be an ObservableCollection so the gui gets notified when it changes.
Hope it helps!
If you switched to ObservableCollection<MyObject> you can bind using VisibilityConverters to that your myList.Count all in XAML. If you are having issues because you are setting the ItemsSource in codebehind, you may want to have it be a resource or switch to something more MVVM.

Dependency Property to fill list or array

I have a custom control. This has the ability to do something with several other Controls. I would like it to have an element NotifyControl where I can bind some other controls like NotifyControl="{Binding ElementName=controlA}". This is fine but I would like to write down n controls. So maybe a list in the element value or noting the element multiple times. Like
<MyControl NotifyControl="{Binding ElementName=a}" NotifiyControl="{Binding ElementName=b}" />
or
<MyControl NotifyControl="{Binding ElementName=a}, {Binding ElementName=b}" />
Which one is possible and how do to it? I got no luck with an array type, maybe my notation like above is wrong.
EDIT:
I now have
<MyControl>
<MyControl.NotifyControls>
<NotifyControlWrapper View="{Binding ElementName=details}" Test="entry one" />
<NotifyControlWrapper View="{Binding ElementName=gauge}" Test="e2" />
</MyControl.NotifyControls>
</MyControl>
<OtherControl x:Name="details" />
NotifyControls is a DependencyProperty and filled with two entries, so this part works fine. The source of NotifyControlWrapper is just a class derived from DependencyObject with the two dependency properties View (type INotifyControl) and Test (type String).
As I sayed my list gets two entries with two NotifyControlWrapper. But while Test contains the given String, View is null. Why is that or how to debug?
Neither one in your question is possible. You can't add the same property twice so #1 won't work. You can't add two bindings so #2 won't work. I would add a property NotifyControls as a List type. NotifyControl could still be available as a separate item or to add to the list of controls in NotifyControls. You can add items in Xaml:
<MyControl.NotifyControls>
<ControlWrapper Control="{Binding ElementName=a}"/>
<ControlWrapper Control="{Binding ElementName=b}"/>
</MyControl.NotifyControls>
ControlWrapper would just have a single member property, Control, so that you can specify the binding.
If N is fixed, you can use a MultiBinding (with a converter):
<MyControl>
<MyControl.NotifyControl>
<MultiBinding Converter="...">
<Binding ElementName="controlA" />
<Binding ElementName="controlB" />
<Binding ElementName="controlC" />
<Binding ElementName="controlD" />
<Binding ElementName="controlE" />
...
</MultiBinding>
</MyControl.NotifyControl>
</MyControl>
If N changes, an option would be to add an ObservableCollection<> to your class which you add/remove the controls to, and then bind to it (again, with a converter)
<MyControl NotifyControl="{Binding ElementName=ParentElement, Path=MyObservableCollection, Converter=...}" />

WPF Multibinding string format date

I'm trying to combine 2 fields of information in my grid by using a Multibinding, the multibinding is working fine but I'm having problems when I try to start formating 1 of the fields which is a date in this binding.
The 2 fields are Users Initials i.e. EGJ and the entry date hoping to achieve a combined field looking like "EGJ - 01/01/2011"
Below is where I'm with my existing XAML
<tk:DataGridTextColumn.Binding>
<MultiBinding StringFormat=" {0} - {}{1:dd/MM/yyyy}">
<Binding Path="UserInitials" />
<Binding Path="EntryDate" />
</MultiBinding>
</tk:DataGridTextColumn.Binding>
Any help or pointers are most appreciated
Couldn't see the wood for the trees
Simply removing the empty braces solved my problem.
<tk:DataGridTextColumn.Binding>
<MultiBinding StringFormat=" {0} - {1:dd/MM/yyyy}">
<Binding Path="UserInitials" />
<Binding Path="EntryDate" />
</MultiBinding>
</tk:DataGridTextColumn.Binding>
Thanks to everyone who took the time to look.
Unless you intend to have a leading space in the formatted value you should use this binding instead:
<tk:DataGridTextColumn.Binding>
<MultiBinding StringFormat="{}{0} - {1:dd/MM/yyyy}">
<Binding Path="UserInitials" />
<Binding Path="EntryDate" />
</MultiBinding>
</tk:DataGridTextColumn.Binding>
If the StringFormat starts with a left brace { the XAML parser require you to escape it using a pair of braces {}. Otherwise the parser gets confused because braces also are used in the syntax of markup extensions.
Details are found in the XAML documentation for {} Escape Sequence / Markup Extension.
Perhaps you had the escape sequence correctly placed in the format string initially and the moved things around resulting in the empty pair of braces at the wrong place?

Resources