I have a multibind calling a converter with two bindings. For some reason it does not return anything. I put
<ItemsControl.Width>
<MultiBinding Converter="{StaticResource ResourceKey=TimelineWidthConverter}">
<Binding Path="AnimationManager.MaxFrame" ElementName="UC" />
<Binding Path="AnimationManager.CurrentZoom" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:TimelineAnimationView}}" />
</MultiBinding>
</ItemsControl.Width>
in the XAML file, and the converter reads:
internal class MaterialTimelineWidthConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (values == null || values.Length != 2 || ReferenceEquals(values[0], DependencyProperty.UnsetValue) || ReferenceEquals(values[1], DependencyProperty.UnsetValue))
{
return 240;
}
var maxFrame = System.Convert.ToInt32(values[0]);
var currentZoom = System.Convert.ToInt32(values[1]);
return currentZoom*maxFrame;
}
public object[] ConvertBack(object values, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
The weird thing is that, if I change the XAML file to be:
<ItemsControl.Width>
280
</ItemsControl.Width>
It works, but if I simply return 280 in the converter it just doesn't do anything. It's as if it just returns nothing but it gives no errors.
The converter worked before, when it was only a single value converter (traditional binding, no multibinding), but as soon as I added the second property and made it multi it does not work. Any tips?
The value returned by a multi-value converter must exactly match the type of the target property. Hence it must a return a double
value, not an int
.
You will also have to do a correct conversion of the two input values. Your current code assumes that both the MaxFrame
and the CurrentZoom
properties of the AnimationManager class are of type int
. In case they are actually double
s, change the conversion appropriately.
public object Convert(
object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null || values.Length != 2 ||
ReferenceEquals(values[0], DependencyProperty.UnsetValue) ||
ReferenceEquals(values[1], DependencyProperty.UnsetValue))
{
return 240d;
}
var maxFrame = System.Convert.ToInt32(values[0]); // or ToDouble
var currentZoom = System.Convert.ToInt32(values[1]); // or ToDouble
return (double)(currentZoom * maxFrame);
}
A probably better implementation might check if the input value are actually ints or doubles (and thus also eliminate the check for UnsetValue
):
public object Convert(
object[] values, Type targetType, object parameter, CultureInfo culture)
{
double result = 240d;
if (values != null && values.Length == 2 &&
values[0] is int && values[1] is int)
{
var maxFrame = (int)values[0];
var currentZoom = (int)values[1];
result = (double)(currentZoom * maxFrame);
}
return result;
}