microsoft / microsoft-ui-xaml

Windows UI Library: the latest Windows 10 native controls and Fluent styles for your applications
MIT License
6.36k stars 678 forks source link

ElementName bindings don't work inside ItemsRepeater DataTemplate #560

Closed JohnnyWestlake closed 3 months ago

JohnnyWestlake commented 5 years ago

Describe the bug As described, using ElementName bindings inside the datatemplate of an Items Repeater appears to fail. The same template inside anything that inherits ItemsControl works fine.

Steps to reproduce the bug

Steps to reproduce the behavior:

  1. Create an ItemsRepeater
  2. Inside it's DataTemplate, use an elementname binding to something outside of the ItemsRepeaters VisualTree.
  3. Observe infinite nothingness

Expected behavior It works.

Version Info O.S. 18362.53 MinVersion SDK: 17134 MaxVersion SDK: 17763

NuGet package version: 2.1.190405004

JohnnyWestlake commented 3 years ago

Is there any follow up on this? Almost 2 years later and it seems like a pretty big thing to be missing, especially if we want ItemsRepeater to replace ListView/GridView, where it works fine.

crodeheaver commented 3 years ago

I'm also running into the same issue. Are there any work arounds for the issue?

LanceMcCarthy commented 2 years ago

@jevansaks I can confirm this bug is still present. I've tried both ElementName and RelativeSource bindings, nothing seems to be able to change the DataContext of that binding as long as it's inside the DataTemplate.

jevansaks commented 2 years ago

I'm sorry to hear that. @RealTommyKlein @ranjeshj any ideas?

agneszitte commented 1 year ago

I'm also running into the same issue even with the latest versions. (cc @michael-hawker)

michael-hawker commented 1 year ago

This is a pain see folks hit trying to implement MVVM patterns. This effects both WinUI 2 and WinUI 3.

Someone recently created a nice isolated repro of the ItemsControl/ItemsRepeater difference here on one of our bugs, thanks to @leoshusar:

<ItemsControl ItemsSource="{x:Bind ViewModel.Items}">
    <ItemsControl.ItemTemplate>
        <DataTemplate x:DataType="x:String">
            <ComboBox Name="cmbTest1">
                <ComboBoxItem Content="TextBlock" Tag="TextBlock" />
                <ComboBoxItem Content="HyperLink" Tag="HyperLink" />
                <i:Interaction.Behaviors>
                    <ic:EventTriggerBehavior EventName="SelectionChanged">
                        <ic:EventTriggerBehavior.Actions>
                            <ic:InvokeCommandAction Command="{Binding ElementName=PageRoot, Path=ViewModel.Test1Command}" CommandParameter="{Binding ElementName=cmbTest1}" />
                        </ic:EventTriggerBehavior.Actions>
                    </ic:EventTriggerBehavior>
                </i:Interaction.Behaviors>
            </ComboBox>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

<ItemsRepeater Grid.Column="1" ItemsSource="{x:Bind ViewModel.Items}">
    <ItemsRepeater.ItemTemplate>
        <DataTemplate x:DataType="x:String">
            <ComboBox Name="cmbTest2">
                <ComboBoxItem Content="TextBlock" Tag="TextBlock" />
                <ComboBoxItem Content="HyperLink" Tag="HyperLink" />
                <i:Interaction.Behaviors>
                    <ic:EventTriggerBehavior EventName="SelectionChanged">
                        <ic:EventTriggerBehavior.Actions>
                            <ic:InvokeCommandAction Command="{Binding ElementName=PageRoot, Path=ViewModel.Test2Command}" CommandParameter="{Binding ElementName=cmbTest2}" />
                        </ic:EventTriggerBehavior.Actions>
                    </ic:EventTriggerBehavior>
                </i:Interaction.Behaviors>
            </ComboBox>
        </DataTemplate>
    </ItemsRepeater.ItemTemplate>
</ItemsRepeater>

https://github.com/CommunityToolkit/Labs-Windows/assets/13891066/aa78f395-23d7-440f-b755-13884730cca8

App22.zip

FYI @bpulliam

AndrewKeepCoding commented 1 year ago

Here's a sample app project with a workaround that works for me.

If you want to see it in action, here's a video.

LeonSpors commented 1 year ago

Any ETA for this issue?

ranjeshj commented 1 year ago

Not sure what ItemsControl is doing to make this work. Here is a simpler repro

    <StackPanel>
        <Button x:Name="button" Content="MyButton" />
        <ItemsRepeater x:Name="repeater">
            <ItemsRepeater.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding ElementName=button, Path=Content}" />
                </DataTemplate>
            </ItemsRepeater.ItemTemplate>
        </ItemsRepeater>
    </StackPanel>

    repeater.ItemsSource = Enumerable.Range(0, 10);

There is a small typo in the repro steps above - cmbTest2 does not exist.

JohnnyWestlake commented 1 year ago

I would presume it is a XAML namescope issue as ElementName requires the element to be in the same namescope, but as we can't debug the namescoping externally someone MS related will have to track it down. But given how "non-traditional" ItemsRepeater layouts are handled compared to normal Xaml ItemsControls I would imagine there's an obvious break point. It could be that elements are namescoped to the RecyclePool for example.

ghost1372 commented 1 year ago

@bpulliam any news? i can not use new control ItemsView because of this bug.

michael-hawker commented 1 year ago

Here's a sample app project with a workaround that works for me.

I wouldn't call adding Loading events to set properties in code-behind as a workaround to a binding issue; sure it may work, but it's so much extra code for each UIElement and property compared to the original binding.

x:Bind/Binding is just broken in so many of these scope scenarios which adds so much friction in developing with XAML (see #2508). If a bit of focus could be spent in this space, it could make the platform a dream to work with.

ghost1372 commented 1 year ago

@duncanmacmichael any new for this?

AndrewKeepCoding commented 1 year ago

I wouldn't call adding Loading events to set properties in code-behind as a workaround to a binding issue; sure it may work, but it's so much extra code for each UIElement and property compared to the original binding.

@michael-hawker I totally agree with you. It's not clean and it's too much extra code for a simple binding. I just had a case that needed to make it work. This issue and #2508 are getting very old and I'm concerned if they will ever get fixed.

duncanmacmichael commented 1 year ago

@duncanmacmichael any new for this?

I'm honestly not sure since engineering handles bugs directly and I'm a PM, but it looks like @ranjeshj is working on this so we can ask him for an update. :)

ranjeshj commented 1 year ago

@RealTommyKlein helped narrow this down to this code - https://github.com/microsoft/microsoft-ui-xaml/blob/7198c4e69019516fb08ecb3937492ffff5fe9702/dxaml/xcp/dxaml/lib/FrameworkElement_partial.cpp#L1169 ItemsRepeater is not an ItemsHost so it is being skipped from this check.

ghost1372 commented 9 months ago

@ranjeshj any update?

ghost1372 commented 8 months ago

@llongley fixed in v1.5 or v1.4.5?

codendone commented 8 months ago

@ghost1372 This is fixed in the upcoming release of v1.5.

DominicMaas commented 6 months ago

This doesn't appear to be fixed? (1.5.240404000), anyone else here still encountering the issue?

ranjeshj commented 6 months ago

The simple repro I had works on latest 1.5 release. https://github.com/microsoft/microsoft-ui-xaml/issues/560#issuecomment-1699459932.

@DominicMaas is your repro different? can you file a new issue with your repro (preferably small/standalone)

ghost1372 commented 6 months ago

The simple repro I had works on latest 1.5 release. #560 (comment).

@DominicMaas is your repro different? can you file a new issue with your repro (preferably small/standalone)

Please test with this repro https://github.com/microsoft/microsoft-ui-xaml/issues/560#issuecomment-1601316553

AathifMahir commented 6 months ago

Still Facing this Issue on Windows App SDK v1.5.240404000

VigneshVoid commented 5 months ago

Same here still facing the issue.

AndrewKeepCoding commented 4 months ago

I run my repro project with all v1.5.x available versions but none of them worked.

leohu1 commented 3 months ago

@RealTommyKlein helped narrow this down to this code -

https://github.com/microsoft/microsoft-ui-xaml/blob/7198c4e69019516fb08ecb3937492ffff5fe9702/dxaml/xcp/dxaml/lib/FrameworkElement_partial.cpp#L1169 ItemsRepeater is not an ItemsHost so it is being skipped from this check.

The same thing happens to ItemsView, I believe.

ghost1372 commented 3 months ago

it seems that issue fixed in v1.6-exp2 vvv