I'm trying to make some XAML fragments more readable (not production code, just for me to get a better understanding of XAML inner workings).
The original code is
<CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}}">
I've changed it to
<CheckBox>
<CheckBox.IsChecked>
<Binding Path="IsSelected" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
<Binding.Source>
<RelativeSource Mode="FindAncestor" AncestorType="{x:Type DataGridRow}"/>
</Binding.Source>
</Binding>
</CheckBox.IsChecked>
</CheckBox>
The first form works ok (it properly binds the IsChecked property of the CheckBox to the IsSelected property of the container (a DataGridRow).
The second one does not work.
How should it look to work properly?
This is because you have set <Binding.Source> instead of <Binding.RelativeSource> in second case. If you set <Binding.RelativeSource> it will work too.
<CheckBox>
<CheckBox.IsChecked>
<Binding Path="IsSelected" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
<Binding.RelativeSource>
<RelativeSource Mode="FindAncestor" AncestorType="{x:Type DataGridRow}"/>
</Binding.RelativeSource>
</Binding>
</CheckBox.IsChecked>
</CheckBox>
Related
I have a class with many properties (not in a list) which must be switchable in view. The converter itself works fine using multibinding.
<TextBox Grid.Row="1" Grid.Column="5">
<TextBox.Text>
<MultiBinding Converter="{StaticResource IntValueConvertor}">
<Binding Path="property1" />
<Binding Path="IntegerDisplay" />
</MultiBinding>
</TextBox.Text>
</TextBox>
In the code, "IntegerDisplay" is a property which is defined in my VM.
Property1 is one of the many properties which must be viewed differently (depending on IntegerDisplay).
What I want to avoid is the need of adding the whole multibinding convertor to each textbox.
Something in this style:
<TextBox
Grid.Row="1"
Grid.Column="4"
Text="{Binding Path=Property1, Converter={StaticResource IntValueConvertor}}" />
I know this code does not work!
I tried using a style, but I could not get to the value of property1.
Is it the best way to use a style or is a datatemplate better?
Kind regards
I recommend sticking with a style and here's a basic start to doing so.
<!--This will go in your resources-->
<Style x:Name="TextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Text" Value="{Binding Path=Property1, Converter={StaticResource IntValueConverter}, ConverterParameter=IntegerDisplay}"/>
</Style>
<!--This will go in your Display-->
<TextBox Style="{StaticResource TextBoxStyle}"/>
I have an interface with multiple buttons. I'd like to enable or disable these buttons according to a 'complex' condition. I declared this MultiBinding as an application resource in order to avoid code repetition:
<MultiBinding x:Key="MyMultiBinding" Converter="{StaticResource ResourceKey=MyConverter}">
<Binding Path="IsConnected" />
<Binding Path="IsOpened" />
</MultiBinding>
Here is how I declare my button:
<Button Name="MyButton" Content="Click me!" IsEnabled="{StaticResource ResourceKey=MyMultiBinding}" />
At runtime, I get the following error: "Set property IsEnabled threw an exception... MultiBinding is not a valid value for property IsEnabled".
I can't figure why this is not working. Could you please point me to the right way to do this? Thank you.
You can't set the boolean IsEnabled property to a value of type MultiBinding. That is what is happening.
As #Viv pointed out, you could declare a Style to do the heavy lifting:
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="IsEnabled">
<Setter.Value>
<MultiBinding Converter="{StaticResource ResourceKey=MyConverter}">
<Binding Path="IsConnected" />
<Binding Path="IsOpened" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
<Button Name="MyButton" Content="Click me!" Style="{StaticResource ButtonStyle}" />
This works well if the Button DataContext has those properties. It works especially well if they each have a different DataContext they are bound to, enabling them for different reasons.
If they are all bound to the same DataContext, or the properties are on a different object, you could use the Freezable Trick to provide a value that your buttons would bind to:
<BindingProxy x:Key="isEnabled">
<BindingProxy.Data>
<MultiBinding Converter="{StaticResource ResourceKey=MyConverter}">
<Binding Path="IsConnected" />
<Binding Path="IsOpened" />
</MultiBinding>
</BindingProxy.Data>
</BindingProxy>
<Button Name="MyButton" Content="Click me!" IsEnabled="{Binding Data, Source={StaticResource isEnabled}}" />
I don't know if this is the best solution, but wrapping the MultiBinding into a style, as Viv said, did the trick. Here is the code of the Style :
<Style x:Key="MyStyle" TargetType="Button">
<Style.Setters>
<Setter Property="IsEnabled">
<Setter.Value>
<MultiBinding Converter="{StaticResource ResourceKey=MyConverter}">
<Binding Path="IsConnected" />
<Binding Path="IsDataAccessOpened" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
And the code of the button :
<Button Name="MyButton" Content="Click me!" Style={StaticResource ResourceKey=MyStyle} />
Is there a way have a single textbox bind to two things. I want to have one binding set to "OneWay" and the Other set to "OneWayToSource". Basically I want to combine these two textboxes into one (and preferably with little to no code behind).
<TextBox Text="{Binding Path=ActionParameter.Value, Mode=OneWayToSource}" />
<TextBox Text="{Binding Path=StatusSignal.Value, Mode=OneWay}" />
You can use MultiBinding to set 2 or more bindings to your TextBox
Example:
<TextBox>
<TextBox.Text>
<MultiBinding StringFormat="{}{0}{1}">
<Binding Path="ActionParameter.Value" Mode="OneWayToSource" />
<Binding Path="StatusSignal.Value" Mode="OneWay" />
</MultiBinding>
</TextBox.Text>
</TextBox>
But depending on what you need to do with the 2 properties you may need to use a IMultiValueConverter to process the properties.
Example:
<TextBox>
<TextBox.Resources>
<local:TextConverter x:Key="MyConverter"/>
</TextBox.Resources>
<TextBox.Text>
<MultiBinding Converter="{StaticResource MyConverter}">
<Binding Path="ActionParameter.Value" Mode="OneWayToSource" />
<Binding Path="StatusSignal.Value" Mode="OneWay" />
</MultiBinding>
</TextBox.Text>
</TextBox>
I have the following code -
<igEditors:XamComboEditor ItemsSource="{Binding Instances}"
Margin="5,2,5,2" Width="175" HorizontalAlignment="Left"
SelectedItem="{Binding SelectedInstance,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnDataErrors=True,ValidatesOnExceptions=True}"
>
<igEditors:XamComboEditor.ComboBoxStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="Name" />
<Binding Path="Id" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</igEditors:XamComboEditor.ComboBoxStyle>
</igEditors:XamComboEditor>
When I set the SelectedInstance from my viewmodel, the combobox is displaying the type of the object. If I then make a selection, it displays correctly, but I click out of the combobox, losing focus, it reverts back to the object type. If I set the DisplayMemberPath manually to just Name, it works correctly, but I really need it to be a concatenated value for the displaymemberpath.
Can anyone help?
Thanks
The answer to this question was to use the ValueToDisplayTextConverter along with a custom converter. More details can be found here -
http://www.infragistics.com/community/forums/p/77378/390782.aspx
I have a multi-binding like
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource myConverter}">
<Binding Path="myFirst.Value" />
<Binding Path="mySecond.Value" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
And I want to pass a fixed value e.g. "123" to one of the two bindings above. How can I do that using XAML?
If your value is simply a string, you can specify it as a constant in the Source property of a binding. If it is any other primitive data type, you need to define a static resource and reference this.
Define the sys namespace in the root of the XAML to point to System in mscorlib, and the following should work:
<TextBlock>
<TextBlock.Resources>
<sys:Int32 x:Key="fixedValue">123</sys:Int32>
</TextBlock.Resources>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource myConverter}">
<Binding Path="myFirst.Value" />
<Binding Source="{StaticResource fixedValue}" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Or, combining the two answers above:
Define the namespace sys at the document head:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
and then:
<MultiBinding Converter="{StaticResource ScalingConverter}">
<Binding>
<Binding.Source>
<sys:Double>0.5</sys:Double>
</Binding.Source>
</Binding>
<Binding ElementName="TC" Path="ActualWidth" />
</MultiBinding>
Which provides the right type without the Resources kludge.
I don't quite follow the question but there are two options:
Put the line <Binding Source="123" /> in your multibinding will pass 123 as a bound value to your converter.
Put ConverterParameter="123" in your MultiBinding:
<MultiBinding Converter="{StaticResource conv}" ConverterParameter="123">
I'm not saying this an especially good answer but here is another approach:
<Binding Path="DoesNotExist" FallbackValue="123" />