Enable a Button When any of Checkboxes on Windows is Checked - wpf

I have 3 CheckBoxes on Windows. I want to enable Button When any of this CheckBoxes is Checked by using binding. I know tips like this :
<Button IsEnabled={Binding ElementName=CheckBox1,Path=IsChecked} />
but I want button bind to other 2 CheckBox.
How to do this?

you can use MultiBinding with a MultiValueConverter
<Button>
<Button.IsEnabled>
<MultiBinding Converter={StaticResource MultiCheckedToEnabledConverter}>
<Binding ElementName="CheckBox1" Path="IsChecked" />
<Binding ElementName="CheckBox2" Path="IsChecked" />
<Binding ElementName="CheckBox3" Path="IsChecked" />
</MultiBinding>
</Button.IsEnabled>
</Button>
public class MultiCheckedToEnabledConverter : IMultiValueConverter
{
#region Implementation of IMultiValueConverter
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
if (values != null) {
return values.OfType<bool>().Any(b => b);
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
return new object[] {};
}
#endregion
}
hope this helps

Related

WPF: pass my TextBox into my converter with my Property together

So i have this Converter:
public class ComboboxSelectedIndexToTextBoxBackgroundColor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int selectedIndex = (int)value;
if (selectedIndex == 0)
return "Red";
else
return "Green";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
My binding object has this Property (implement INotifyPropertyChanged):
public int ComboboxSelectedIndex
{
get { return _comboboxSelectedIndex; }
set
{
_comboboxSelectedIndex = value;
OnPropertyChanged();
}
}
My TextBox:
<TextBox Controls:TextBoxHelper.ClearTextButton="False"
Background="{Binding ComboboxSelectedIndex, Converter={StaticResource ComboboxSelectedIndexToTextBoxBackgroundColor}}"
Margin="0,0,0,0">
So if i want to use MultiBindingConverter and along my ComboboxSelectedIndex property i want slao to sent my TextBox - is it possible ?
How can i do that ?
add Name="txt" attribute to TextBox and use ElementName in binding. TextBox will become the source of binding and without property Path it will be send to converter itself, not property value.
<MultiBinding Converter="{StaticResource MvCvt}" Mode="OneWay">
<Binding Path="ComboboxSelectedIndex"/>
<Binding ElementName="txt"/>
</MultiBinding>
element can also send itself to binding using {RelativeSource Self}
<MultiBinding Converter="{StaticResource MvCvt}" Mode="OneWay">
<Binding Path="ComboboxSelectedIndex"/>
<Binding RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
"McCvt" is a some IMultiValueConverter implementation here

wpf - checkbox.isvisible is ture when one of the radio button is checked or no radio button checked

I am new to Wpf
i have a group of 3 radio buttons
for all the checkbox, it is not visible when none of the radio button is chekced or the third radio button on the group is checked.
I wonder if there is a way to achieved this?
I attempt built in booleanToVisibility but it does not work.
do i need to use something like multiple data trigger? thanks!
You are right about MultiBinding. Your Xaml should look like this:
<Window.Resources>
<local:MultiBoolToVisibilityConverter x:Key="MultiBoolToVisibilityConverter"/>
</Window.Resources>
<DockPanel>
<StackPanel DockPanel.Dock="Top">
<RadioButton Name="rb1" Content="1"/>
<RadioButton Name="rb2" Content="2"/>
<RadioButton Name="rb3" Content="3"/>
</StackPanel>
<CheckBox DockPanel.Dock="Bottom" Content="Visible when 1 or 2 is checked.">
<CheckBox.Visibility>
<MultiBinding Converter="{StaticResource MultiBoolToVisibilityConverter}">
<Binding Path="IsChecked" ElementName="rb1" />
<Binding Path="IsChecked" ElementName="rb2" />
<Binding Path="IsChecked" ElementName="rb3" />
</MultiBinding>
</CheckBox.Visibility>
</CheckBox>
</DockPanel>
The MultiBoolToVisibilityConverter in the converter should be defined in code behind, implementing IMultiValueConverter
public class MultiBoolToVisibilityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
bool? firstRadioButtonIsChecked = values[0] as bool?;
bool? secondRadioButtonIsChecked = values[1] as bool?;
bool? thirdRadioButtonIsChecked = values[2] as bool?;
//set your logic. this is just an example:
if (firstRadioButtonIsChecked == true || secondRadioButtonIsChecked == true)
return Visibility.Visible;
return Visibility.Collapsed;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
for further questions, you can see this post on MultiBinding and IMultiValueConverter among other google suggestions.

PropertyChangedTrigger For Multiple Properties?

Is there a way to create PropertyChangedTrigger for multiple properties that all share the same conditions, for the sake of redundancy, without specifying the conditions repeatedly for each PropertyChangedTrigger?
For example, when PropertyA, PropertyB and PropertyC change, I want a command to execute in my ViewModel.
I was thinking of something like extending the PropertyChangedClass and adding a dependency property of a an observable collection of Bindings. But it turned out I'm not very knowledgeable in how Bindings are monitored.
Then I saw some of old code and saw Multibinding. I thought it could work. And it did with a MultiValueConverter that just increments a static field. I'm not sure if this is the best solution but this worked.
First the MultiValueConverter:
public class IncrementOnPropertyChangedMultiConverter:IMultiValueConverter
{
static uint _counter=0;
#region IMultiValueConverter Members
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
_counter = _counter < uint.MaxValue ? _counter + 1 : 0;
return _counter;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
Then in XAML you just add a MultiBinding instead of Binding in the PropertyChangedTrigger.
<i:Interaction.Triggers>
<ei:PropertyChangedTrigger>
<ei:PropertyChangedTrigger.Binding>
<MultiBinding Converter="{StaticResource IncrementOnPropertyChangedMultiConverter}">
<Binding Path="Property1" />
<Binding Path="Property2" />
<Binding Path="PropertyN" />
</MultiBinding>
</ei:PropertyChangedTrigger.Binding>
<i:Interaction.Behaviors>
<ei:ConditionBehavior>
<ei:ConditionalExpression>
<ei:ComparisonCondition LeftOperand="{Binding Property1}"
Operator="Equal"
RightOperand="{Binding Property2}" />
</ei:ConditionalExpression>
</ei:ConditionBehavior>
</i:Interaction.Behaviors>
<ei:ChangePropertyAction PropertyName="Background"
Value="Transparent" />
</ei:PropertyChangedTrigger>
<i:Interaction.Triggers>

Switching Binding Sources using a MultiBinding

I have a DataBinding with a MultiBinding of two ObservableCollections, and i want to switch between them on a condition with a MultiConverter.
So the converter gives the right collection, but the binding doesn't seem to be updated.
Any Ideas??
Greets,
Jürgen
This is the converter you need:
public class SwitchCollectionsConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool b = (bool)values[2];
if (b)
return values[0];
else
return values[1];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
registering the converter:
<local:SwitchCollectionsConverter x:Key="TheConverter" />
usage of the binding:
<ItemsControl>
<ItemsControl.ItemsSource>
<MultiBinding Converter="{StaticResource TheConverter}">
<Binding Path="FirstCollection" />
<Binding Path="SecondCollection" />
<Binding Path="IsFirst" />
</MultiBinding>
</ItemsControl.ItemsSource>
</ItemsControl>
under the assumption that you have a FirstCollection, a SecondCollection, and an IsFirst Properties in the DataContext
Do you need the view to update the source lists?
If so, your binding should be in TwoWay mode:
<TextBox Text="{Binding Source, Mode="TwoWay"}" />

Enabling/disabling control based on values of more than one control in WPF

Can I control the enabling/disabling of my textbox using a checkbox and a radio-button, both?
My UI is such that the checkbox controls the individual textbox state, while a radio button controls the enable/disable states of both the textbox and the checkbox.
You can perform this in the UI using a multibinding. This would look like this:
<TextBlock>
<TextBlock.IsEnabled>
<MultiBinding Converter="{StaticResource MultiConverter}">
<Binding ElementName="MyCheckBox" Path="IsChecked" />
<Binding ElementName="MyRadioButton" Path="IsChecked" />
</MultiBinding>
</TextBlock.IsEnabled>
</TextBlock>
<CheckBox x:Name="MyCheckBox"/>
<RadioButton x:Name="MyRadioButton"/>
Where the converter looks at the checked state of the radio and checkbox
public class MultiConverter: IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
bool isCheckBoxChecked = (bool)value[0];
bool isRadioButtonChecked = (bool)value[1];
return isCheckBoxChecked && isRadioButtonChecked;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}

Resources