1

Disclaimer: not that I cannot resolve the problem, but I'm curious why the problem occurs in the first place.

A typical scenario: placing a bunch of things within a data template into some Tag. The end goal is to have an array of controls inside that tag. As I'm binding to object type property, I have to use the convertor.

<Button Content="Test" >
    <Button.Tag>
        <MultiBinding Converter="{StaticResource mbc}">
            <Binding ElementName="sdbr"/>
            <Binding ElementName="ldbr"/>
        </MultiBinding>
    </Button.Tag>
</Button>

The mbc is a converter instance of this type:

public class MultiConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return values; //<--This here is a line of interest
    }
... ConvertBack is default;

Now, the problem: even though input values contains proper data, Tag gets new object[]{null, null} as the resulting value. As long as I return anything different from an input array - it works just fine. All of these work properly:

return values.Clone(); /*option a*/
return new List<object>(values); /*option b*/
return values.Cast<Whatever>().ToList(); /*option c*/

I checked but couldn't find anywhere requirement to return anything except the input value on MSDN. And besides, even if such a thing would exist, why on Earth would it return me an array of proper length but with nulls inside?!

Mike Makarov
  • 1,287
  • 8
  • 17
  • I don't really know for sure (no opportunity right now to test this myself), but it could be that the binding mechanism re-uses the input values array instance again somehow somewhere, and placing other values in it (in your case `null`). At least it looks to me like that, based on your explanation... –  Dec 05 '18 at 11:51
  • I suppose it is a question of how conversion to object[] and from object[] works. – Belurd Dec 05 '18 at 11:59
  • 1
    @Belurd, what are you getting at precisely? The type of the `FrameworkElement.Tag` property is `object`, so there is no conversion of whatever the `IMultiValueConverter.Convert` method decides to return. (Assuming hypothetically that some conversion would takeplace, how would you explain that simply cloning the input values array works? Should it rather not work too if some "hidden" conversion is taking place?) –  Dec 05 '18 at 12:17
  • 1
    I took a quick look into source code (hopefully right place) and @elgonzo is right, the binding mechanism re-uses that array and after each transfer (source->target) `Array.Clear` is called. See lines 56,1184,1267 https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Data/MultiBindingExpression.cs – nosale Dec 05 '18 at 13:53
  • @nosale you are right, this line looks to be the answer, though it doesn't really answer as for *why* this is done: https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Data/MultiBindingExpression.cs,1267 To me it looks like some design miss resulting in an unnecessary limitation. – Mike Makarov Dec 05 '18 at 14:08
  • 2
    @MikeMakarov For this i think you have to ask Microsoft directly. We can only guess why. If you are interested in my opinion I think it is performance related, cause re-use is more efficient than re-creation and returning the input in a converter isn't the normal case. – nosale Dec 05 '18 at 14:20

0 Answers0