Open shcholeh opened 1 year ago
@shcholeh Sorry for the late response here. I didn't see this issue until now.
In WPF (and likely other platforms?), Binding
and MultiBinding
work differently in the case where the value(s) are UnsetValue
.
Binding
will return FallbackValue
if the binding source does not successfully resolve. So, in your case, since you haven't set FallbackValue
, the binding automatically returns UnsetValue
without even trying to use MathConverter
(and therefore falls back to the default value for Visibility
, which is System.Windows.Visibility.Visible
).MultiBinding
will not use FallbackValue
nearly as aggressively. See this post for details. In your case, it's still trying to use MathConverter with UnsetValue
, and you're not properly handling the case where UnsetValue
is passed for x
and y
.You can certainly use TryCatch
in this scenario, but catching exceptions is very inefficient, so I would recommend against using TryCatch
unless absolutely necessary (e.g. if you're trying to convert a user-input value to float, and you don't want to crash the application if the user types something that's not a number).
The SanitizeBinding
method automatically converts UnsetValue
to null
(unless you've set AllowUnsetValue
to true on the MathConverter). So, you're likely evaluating the expression null || null ? `Visible` : `Collapsed`
, and that's throwing an exception. I would try something like ((x || y) ?? false) ? `Visible` : `Collapsed`
for your ConverterParameter
to get rid of the exception and to give it a fallback value of Collapsed
if both of the bindings cannot return a value.
Thank you for explanations and nice link that I added to my collection - not always find nice answers when search the web.
'(x || y) ?? false' solved my case too - seem to perform faster than catching exceptions in debug mode. However observed a number of
Encountered UnsetValue in the 1st argument while trying to convert to type "System.Windows.Visibility" using the ConverterParameter "((x || y) ?? false) ? Visible
: Collapsed
". Double-check that your binding is correct.
Encountered UnsetValue in the 2nd argument while trying to convert to type "System.Windows.Visibility" using the ConverterParameter "((x || y) ?? false) ? Visible
: Collapsed
". Double-check that your binding is correct.
in output of VS after normal program termination, hope they are just for information.
I made before a number of trials with FallbackValue and TargetNullValue experiments that failed with MultiBinding before I understood that it is not simple. Here I just wanted clean up messages and tried to set FallbackValue once more.
With FallbackValue=False
I got same list and normal operation. Never knew that in MultiBinding should set in childs FallbackValue expected result in Target. So set FallbackValue=Collapsed
for each child and got suddenly exception:
FallbackValue values didn't bypass Converter directly to Target but should, or I've misunderstood something. Additional FallbackValue in Converter doesn't help. FallbackValue=false
, FallbackValue='false'
and
[sys:Boolean x:Key="FalseValue"]False [sys:Boolean]
with FallbackValue={StaticResource FalseValue}
tried also - not seen at all but Visibility passed in a glance.
Here, for example:
Text="{math:Convert '$
hex.: {x}, dec.: {y}', x={Binding XPath=@code, FallbackValue=''}, y={Binding XPath=@dec, FallbackValue=''}}"
I get rid of debug messages where UnsetValue values passed from Binding when DataContext is not yet set. But empty string here is indistinguishable from null and doesn't harm at all, at least no operations here - just ToString().
Sorry if bother you too much ;) Just want to help a bit and get help too
Why does MultiBinding with a Converter not work within a ToolTip
Same story was observed by me while using in ContextMenu. Exception raises after click in Menu when ContextMenu starts to close and loses PlacementTarget or its DataContext. If use Binding it has no impact but for MultiBinding yes.
Here is the exception:
MathConverter threw an exception while performing a conversion.
System.InvalidOperationException: Cannot apply operator '?:' when the first operand is null ConverterParameter: x || y ? `Visible` : `Collapsed` BindingValues: [0]: (MS.Internal.NamedObject): {DependencyProperty.UnsetValue} [1]: (MS.Internal.NamedObject): {DependencyProperty.UnsetValue}Workaround with combined DependencyProperty in order to use Binding works nice.
The use of CustomFunction TryCatch solved my case now.
But what if in code of MathConverter simply after
add check for DependencyProperty.UnsetValue among sanitizedValues and return Binding.DoNothing. Or TryCatch was implemented for such cases and is more universal for use? Thanks in advance.