34

I have an extremely simple IMultiValueConverter that simply OR's two values. In the example below, I want to invert the first value using an equally simple boolean inverter.

<MultiBinding Converter="{StaticResource multiBoolToVis}">
    <Binding Path="ConditionA" Converter="{StaticResource boolInverter}"/>
    <Binding Path="ConditionB"/>
</MultiBinding>

and the inverter:

public class BoolInverterConverter : IValueConverter
{
    #region IValueConverter Members
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is bool)
        {
            return !((bool)value);
        }
        return null;
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
    #endregion
}

When I include the boolInverter, the first value in the MultiValueConverter becomes a "DependencyProperty.UnsetValue". There are no problems when I do not use the converter (other than not the logic I am aiming for, of course).

Am I missing something? Stepping through the debugger shows that the InverseBoolConverter is properly inverting the value I pass it, but that value is then not being 'sent' to the MultiValueConverter.

Askolein
  • 3,250
  • 3
  • 28
  • 40
Erik Kerber
  • 5,646
  • 7
  • 38
  • 56
  • see this one: http://stackoverflow.com/questions/683863/items-collection-must-be-empty-before-using-itemssource – mkb Sep 22 '15 at 11:36

3 Answers3

40

From MSDN:

UnsetValue is a sentinel value that is used for scenarios where the WPF property system is unable to determine a requested DependencyProperty value. UnsetValue is used rather than null reference (Nothing in Visual Basic), because null reference could be a valid property value, as well as a valid (and frequently used) DefaultValue.

Which means one of the following things:

  • You use a template (ControlTemplate or DataTemplate), and the value does not have a DataSource set at the time of being Loaded. So it will hit your converter twice, first with the UnsetValue, second with the boolean value; so nothing to worry about;
  • Your Binding is incorrect, meaning the Binding cannot determine a value, thus resulting in the UnsetValue.. You should propbably see a warning..

Also, you cannot combine Converters like you do.. So its probably that.

Remove the Converter in the inner Binding, and it should be fixed! :)

Hope this helps!

Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
Arcturus
  • 26,677
  • 10
  • 92
  • 107
  • Really? So would I have to have a mirror property, "InverseConditionA", to do what I'm trying? Yuck! – Erik Kerber May 11 '10 at 14:29
  • Yeah, or expand your MultiValueConverter with parameters, to invert the first boolean? – Arcturus May 12 '10 at 07:12
  • 1
    How can I check whether a particular 'value' in converter has dependencyproperty.unsetvalue ? I mean if I want to cast the value to Int then it will throw an error like (Int32)value - as value is dependencyproperty.unsetvalue. anyidea? – Rohit Feb 08 '12 at 06:43
  • 3
    Found my answer :) .. by using 'is' i can check. – Rohit Feb 08 '12 at 06:44
  • The Output window displays information about all binding failures. – Trevor Tubbs Aug 14 '14 at 17:52
  • I just had the issue today when i made a control template but forgot to set binding for "Background" to "TemplateBinding Background". It shows the error at design time. – Thai Anh Duc Jun 18 '15 at 02:34
  • 1
    @Rohit I know I'm a few years late, but you can compare directly to the property.`if (value == DependencyProperty.UnsetValue) {// Do Stuff}` Any drawback to this approach? – Tyler StandishMan Apr 22 '16 at 13:45
  • @TylerStandishMan appreciate your response. I've moved on from WPF now. Hoping your response helps someone. – Rohit Apr 22 '16 at 21:52
  • Maybe you can try convert to bool: `bool outTest; if (bool.TryParse(value.ToString(), out outTest) { var a = (bool) value; .... } ` so DependencyProperty.UnsetValue won't be converted. – Fer R Nov 08 '17 at 23:22
5

Just in addition to all other answers, I usually add these lines to the beginning of Convert method:

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Any(x => x == DependencyProperty.UnsetValue))
            return DependencyProperty.UnsetValue;

        ...

    }

to make sure that none of the values is unset (that usually happens with DataGrid with CanUserAddRows="True").

simon
  • 1,161
  • 10
  • 27
0

If occuring in a datagrid try setting CanUserAddRows="False"

Mark Wickman
  • 83
  • 1
  • 9