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
Related
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>
Most converters take no parameters, or one fixed parameter, and are easy to bind to:
<local:MyConverter x:Key="MyConverterInstance" />
<TextBox Text="{Binding Path=MyTime,
Converter={StaticResource MyConverterInstance},
ConverterParameter='yyyy/MM/dd'}" />
But if I want that format to be a dynamic property that the user can change, I can't do something like this, right?:
<TextBox Text="{Binding Path=MyTime,
Converter={StaticResource MyConverterInstance},
ConverterParameter={Binding Path=UserFormat}}" />
So my only option is to define a DependencyProperty on MyConverter for binding. But my converter definition is a StaticResource. I can't go
<local:MyConverter x:Key="MyConverterInstance"
Format="{Binding Path=UserFormat}"/>
because there's no DataContext on StaticResources. How can I set this up?
You cannot bind to a converterparameter but you can use Multibinding instead.
For example: http://www.switchonthecode.com/tutorials/wpf-tutorial-using-multibindings
or How to simply bind this to ConverterParameter?
(Alain) So just to translate that linked answer into something that matches this question:
<TextBlock>
<TextBlock.Resources>
<local:MyConverter x:Key="MyConverterInstance" />
</TextBlock.Resources>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource converter}">
<Binding Path="MyTime" />
<Binding Path="UserFormat" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
public class MyConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
DateTime time = (DateTime)values[0];
string format = values[1].ToString();
return time.ToString(format);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
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
I have the following code.
This displays data in following format H:M:S. I would like to edit these values...and wanted to be notified in viewmodel.
How do I achieve that ?
Any help would be appreciated. Thanks
<TextBox DataContext="{Binding UpdateSourceTrigger=PropertyChanged}" >
<TextBox.Text>
<MultiBinding StringFormat=" {0}:{1}:{2}">
<Binding Path="ValueH" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" />
<Binding Path="ValueM" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" />
<Binding Path="ValueS" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" />
</MultiBinding>
</TextBox.Text>
</TextBox>
StringFormat binding is oneway
What you will need to do is write your own multivalue converter that implements the ConvertBack method as well.
A very simplistic converter would be something like below. You will need to add error checking and there is no doubtly a better way to convert back (possibly with a regex). Plus I'm not sure that I got the DateTime bit right but it gives you a starting point.
public class TimeConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
return string.Format("{0}:{1}:{2}",values[0],values[1],values[2]); }
public object[] ConvertBack(object value, Type[] targetTypes, object parameter,
System.Globalization.CultureInfo culture)
{
var date=DateTime.Parse((string)value);
return new object[] { date.Hours,date.Minutes,date.Seconds };
}
}
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"}" />