I´d like to reuse a MultiBinding and tried to use this solution, but I can´t seem to reach IsEnabled from a Setter Property.
So I tried this approach, but no cigar :
App.xaml
<Application x:Class="Test.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:model="clr-namespace:Test.MODEL"
StartupUri="MainWindow.xaml">
<Application.Resources>
<view:BooleanConverter x:Key="BooleanConverter" />
<view:BooleanMultiConverter x:Key="BooleanMultiConverter" />
<MultiBinding x:Key="OnOffBinding" Converter="{StaticResource BooleanMultiConverter}" ConverterParameter="OR">
<Binding Path="model:CustomerIsDefined" Converter="{StaticResource BooleanConverter}" />
<Binding Path="model:CustomerIsConfirmed" Converter="{StaticResource BooleanConverter}" />
</MultiBinding>
</Application.Resources>
MainWindow.xaml > These two attempts will not compile :
<TextBox IsEnabled="{StaticResource OnOffBinding}"/>
<TextBox IsEnabled="{MultiBinding {StaticResource OnOffBinding}}" />
Any ideas?
EDIT: After accepting Funcs answer I guess this has allready been answered in the linked thread. Sorry..
Try wrapping it in Style
<Application.Resources>
<view:BooleanConverter x:Key="BooleanConverter" />
<view:BooleanMultiConverter x:Key="BooleanMultiConverter" />
<Style x:Key="ControlEnabler" TargetType="Control">
<Setter Property="IsEnabled">
<Setter.Value>
<MultiBinding x:Key="OnOffBinding" Converter="{StaticResource BooleanMultiConverter}" ConverterParameter="OR">
<Binding Path="model:CustomerIsDefined" Converter="{StaticResource BooleanConverter}" />
<Binding Path="model:CustomerIsConfirmed" Converter="{StaticResource BooleanConverter}" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
MainWindow.xaml
<TextBox Style="{StaticResource ControlEnabler}"/>
Note TargetType="Control" making it generic.
I have some RadioButton’s that I want to change the Visibility of based on multiple properties in the ViewModel. Each RadioButton’s Visibility will vary based on the same list of properties. I have the following xaml:
<RadioButton Command="{Binding Path=SomeCommand}"
CommandParameter="SomeCommandParameter"
Content="RB 1">
<RadioButton.Visibility>
<MultiBinding Converter="{StaticResource Rb1Visibility}">
<Binding Path="Value1"
RelativeSource="{RelativeSource Self}" />
<Binding Path="Value2"
RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</RadioButton.Visibility>
</RadioButton>
I would like to change the Converter for each RadioButton option, but everything else would remain the same (all the Bindings). I don’t want to duplicate all the xaml code for this. I originally tried creating a style for the RadioButton, but I could not figure out how to pass the Converter to the Style resource:
<Style x:Key="RbVisibilityStyle"
TargetType="{x:Type RadioButton}">
<Setter Property="Visibility">
<Setter.Value>
<MultiBinding Converter="{???? Pass in converter ?????}">
<Binding Path="Value1"
RelativeSource="{RelativeSource Self}" />
<Binding Path="Value2"
RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
I could create a “Visibility” property for each RadioButton in the ViewModel, but that adds a lot of code to the ViewModel and addition PropertyChanged event handling.
Is there an easy way to generically bubble up the MultiBinding so I don’t duplicate the code throughout the entire xaml file? Is there a different approach I should be taking?
Update - Adding a more complex example
<RadioButton Command="{Binding Path=SomeCommand}"
CommandParameter="SomeCommandParameter"
Content="RB 1">
<RadioButton.Visibility>
<MultiBinding Converter="{StaticResource Rb1Visibility}">
<Binding Path="Value1"
RelativeSource="{RelativeSource Self}" />
<Binding Path="Value2"
RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</RadioButton.Visibility>
</RadioButton>
<RadioButton Command="{Binding Path=SomeCommand2}"
CommandParameter="SomeCommandParameter2"
Content="RB 2">
<RadioButton.Visibility>
<MultiBinding Converter="{StaticResource Rb2Visibility}">
<Binding Path="Value1"
RelativeSource="{RelativeSource Self}" />
<Binding Path="Value2"
RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</RadioButton.Visibility>
</RadioButton>
<RadioButton Command="{Binding Path=SomeCommand3}"
CommandParameter="SomeCommandParameter3"
Content="RB 3">
<RadioButton.Visibility>
<MultiBinding Converter="{StaticResource Rb3Visibility}">
<Binding Path="Value1"
RelativeSource="{RelativeSource Self}" />
<Binding Path="Value2"
RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</RadioButton.Visibility>
</RadioButton>
How do I reduce the MultiBinding redundancy here?
would like to change the Converter for each RadioButton option,
Create a new MultiValueConverter which takes an extra parameter (the radio button option) and then simply route the call to the appropriate converter based on that option.
One can put the option in the Tag property on the control's Xaml.
Example
Its not clear to me what that option you mention is, so in my example let us uniquely identify each Radio Button by its Tag property and use the routing converter to find the appropriate converter based off of the Tag supplied.
<RadioButton Tag="1"/><RadioButton Tag="2"/>
Then change the style to use the new converter with the new parameter:
<Style x:Key="RbVisibilityStyle"
TargetType="{x:Type RadioButton}">
<Setter Property="Visibility">
<Setter.Value>
<MultiBinding Converter="{StaticResource RouterViaTagVisibilityConverter">
<Binding Path="Value1"
RelativeSource="{RelativeSource Self}" />
<Binding Path="Value2"
RelativeSource="{RelativeSource Self}" />
<Binding Path="Tag"
RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
I want to link the DataBinding of a listbox item with a new window
A "Name" button should open a new window with the DataBinding of the listbox item.
The Binding is a .xml File:
<People>
<Person image="Test.jpg" company="" position="" website="" chat="" notes="">
<Name first_name="Max" second_name="" last_name="Mustermann" salutation="" />
<Email email1="" email2="" email3="" />
<Phone_Numbers business="" private="" mobile="" />
<Business_Adress street="" place="" state="" postalcode="" country="" />
<Private_Adress street="" place="" state="" postalcode="" country="" />
</Person>
</People>
And the new Window should be linked to the Name Element of the Person.
Though there will be more then one person, but the window should be linked to the right person.
This is the XmlDataProvider:
<XmlDataProvider x:Name="XmlData" Source="People.xml" XPath="/People/Person" />
And the binding of the listbox looks like this:
<ListBox
Grid.Row="0"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding UpdateSourceTrigger=Explicit}"
x:Name="PeopleListBox"
SelectionMode="Single">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}, {1} {2}">
<Binding XPath="Name/#last_name" />
<Binding XPath="Name/#first_name" />
<Binding XPath="Name/#second_name" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Unless DataContext is set to XmlData your ItemsSource binding won't work. You did not mention where you define XmlDataProvider because if in Resources then you need to specify x:Key instead of x:Name and then you would have to specify it as Binding.Source. You also did not say what is People.xml as it must be added to your solution as a resource
<Window ...>
<Window.Resources>
<XmlDataProvider x:Key="XmlData" XPath="/People/Person" Source="People.xml"/>
</Window.Resources>
<ListBox ItemsSource="{Binding Source={StaticResource XmlData}}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}, {1} {2}">
<Binding XPath="Name/#last_name" />
<Binding XPath="Name/#first_name" />
<Binding XPath="Name/#second_name" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
or you can load it manually by setting XmlDataProvider.Source manually in code
I need to bind a checkBox to TWO property and I think that i have to use multiBindings
so far i have this, but this doesn't work.
<CheckBox x:Name="FilterAll" Content="All">
<CheckBox.IsChecked>
<MultiBinding>
<Binding Path="SearchEngineCompassLogView.FilterSearch.IsFilterAllEnable"
Source="{StaticResource CompassLogView}">
</Binding>
<Binding Path="SearchEngineCompassLogView.FilterSearch.IsFilterVisible"
Source="{StaticResource CoreServiceLogView}">
</Binding>
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
is this even possible with MultiBinding?
You could use MultiBinding. And as ethicallogics said, you must use a converter to do the actual logic of the parameters (whether you want to do AND, OR, whatever. You can see a little more about those here
I'm not sure what you are trying to affect on your checkbox, but in the end it will look something like this.
<CheckBox.IsChecked>
<MultiBinding Converter="{StaticResource MultiBoolConverter}">
<Binding Path="SearchEngineCompassLogView.FilterSearch.IsFilterAllEnable" Source="{StaticResource CompassLogView}"/>
<Binding Path="SearchEngineCompassLogView.FilterSearch.IsFilterVisible"
Source="{StaticResource CoreServiceLogView}"/>
</MultiBinding>
</CheckBox.IsChecked>
There is also another way to do this as well, which I sometimes find useful. It's called DataTriggers. If you've done any work with Styles and Templates then you may have seen them before. Here is an example based on your question:
<CheckBox>
<CheckBox.Style>
<Style TargetType={x:Type CheckBox}>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path="SearchEngineCompassLogView.FilterSearch.IsFilterAllEnable" Source="{StaticResource CompassLogView}" Value="True"/>
<Condition Binding="{Binding Path="SearchEngineCompassLogView.FilterSearch.IsFilterVisible" Source="{StaticResource CoreServiceLogView}" Value="True"/>
</MultiDataTrigger.Conditions>
<Setter Property="CheckBox.IsChecked" Value="True"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
You must specify converter in MultiBinding.Multibinding
I'm working on a user control right now in which I have a path as part of the control. There are 3 possible paths I might want to display based on the values of certain data. To determine which Path I want to use, I have a value converter that takes in the data and returns a number to represent which of the paths I should use.
My first thought was to just use the property changed callback from the two dependency properties I am getting data from, but those callbacks must be static and the XAML code is always non-static.
My second attempt is to now use datatriggers with the value converter described above. Below is the code I have.
<Path x:Name="path" Stretch="Fill" Width="111.75" Height="118.718" Data="F1M205.917,103.0088C189.333,93.8108,170.128,88.9998,150,88.9998C129.873,88.9998,110.584,93.8108,94.167,102.8408L116.1,144.2508L150,208.7178L183.9,144.2508z" Canvas.Left="0" Canvas.Top="0">
<Path.Resources>
<Style TargetType="{x:Type Path}">
<Style.Triggers>
<DataTrigger Value="-1">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource ToleranceRangeTypeChecker}">
<Binding ElementName="UserControl" Path="ToleranceZoneLowerBound" />
<Binding ElementName="UserControl" Path="ToleranceZoneUpperBound" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Data" Value="F1M205.917,103.0088C189.333,93.8108,170.128,88.9998,150,88.9998C129.873,88.9998,110.584,93.8108,94.167,102.8408L116.1,144.2508L150,208.7178L183.9,144.2508z" />
<Setter Property="Width" Value="111.75" />
<Setter Property="Height" Value="118.718" />
<!--<Setter Property="Canvas.SetLeft"-->
</DataTrigger>
<DataTrigger Value="0">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource ToleranceRangeTypeChecker}">
<Binding ElementName="UserControl" Path="ToleranceZoneLowerBound" />
<Binding ElementName="UserControl" Path="ToleranceZoneUpperBound" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Data" Value="F1M150,88.9998C129.873,88.9998,110.584,93.8108,94.167,102.8408L150,208.7178C150,208.7178,150,114.157407529625,150,88.9998z" />
<Setter Property="Width" Value="55.917" />
<Setter Property="Height" Value="118.718" />
<!--<Setter Property="Canvas.SetLeft"-->
</DataTrigger>
<DataTrigger Value="1">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource ToleranceRangeTypeChecker}">
<Binding ElementName="UserControl" Path="ToleranceZoneLowerBound" />
<Binding ElementName="UserControl" Path="ToleranceZoneUpperBound" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Data" Value="F1M205.917,103.0088C189.333,93.8108 170.128,88.9998 150,88.9998 150,113.365662567029 150,208.7178 150,208.7178L183.9,144.2508z" />
<Setter Property="Width" Value="111.75" />
<Setter Property="Height" Value="118.718" />
<!--<Setter Property="Canvas.SetLeft"-->
</DataTrigger>
</Style.Triggers>
</Style>
Another thought I had was to instead actually have 3 different paths and use setters to change the visibility of each, but I think that having one path and changing it's propertise would be more logical. I would also prefer one path because my goal would be to eventually animate between the paths rather than have them change instantly.
Thanks!
You can get the instance by casting the sender parameter in the property change callbacks.