Binding with ElementName doesn't work from within a TreeViewItem
Describe the bug
When using a Binding with ElementName from within a TreeViewItem in a DataTemplate, the binding is not resolved and no binding errors are reported.
Steps to reproduce the bug
<Window
x:Class="App10.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App10"
x:Name="window">
<TreeView ItemsSource="{x:Bind ViewModels}">
<TreeView.ItemTemplate>
<DataTemplate x:DataType="local:Entity">
<TreeViewItem ItemsSource="{x:Bind Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{x:Bind Name}" />
<TextBlock Text="{Binding StuffProcessor.StuffTitle, ElementName=window}" />
</StackPanel>
</TreeViewItem>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Window>
using Microsoft.UI.Xaml;
using System.Collections.Generic;
namespace App10;
public sealed partial class MainWindow : Window
{
public MainWindow() =>
InitializeComponent();
public List<Entity> ViewModels { get; } =
[
new("Parent 1")
{
Children=
[
new("Child 1.1"),
new("Child 1.2"),
new("Child 1.3"),
]
},
new("Parent 2")
{
Children=
[
new("Child 2.1"),
new("Child 2.2"),
new("Child 2.3"),
]
},
];
public string Annotation => "Annotation";
}
public class Entity(string name)
{
public string Name { get; } = name;
public List<Entity> Children { get; set; } = [];
}
Actual behavior
Expected behavior
Annotation property should be accessed and materialized.
Screenshots
No response
NuGet package version
WinUI 3 - Windows App SDK 1.7.0: 1.7.250310001
Windows version
Windows 11 (22H2): Build 22621
Additional context
No response
Dup? https://github.com/microsoft/microsoft-ui-xaml/issues/2508 https://github.com/microsoft/microsoft-ui-xaml/issues/560
Not sure it's the same issue but it's definitely related. That issue has been around for 6 years! Binding with ElementName is a crucial and very common functionality in any XAML app. Not fixing or addressing an issue of this nature is neglect and disrespect.
Binding != x:Bind so not the same issue as #2508, but can confirm that this is indeed an issue. Possibly related to #560.
I thought maybe this has to do with the weirdness that is Window in WinUI (it's not really a full-class XAML element citizen the same way as other elements like Page/UserControl, it's more a simple wrapper over a native window). I usually just new one up in code at startup and drop a Frame or Page into it and keep all the real code inside other controls to avoid some problems. That said, I tried this, and it also did not work:
<Page x:Class="TestUno.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="{ThemeResource BackgroundBrush}"
x:Name="page">
<ScrollViewer x:Name="sv" Tag="Annotation">
<TreeView ItemsSource="{x:Bind ViewModels}">
<TreeView.ItemTemplate>
<DataTemplate x:DataType="local:Entity">
<TreeViewItem ItemsSource="{x:Bind Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{x:Bind Name}" />
<TextBlock Text="{Binding Tag, ElementName=sv}" />
</StackPanel>
</TreeViewItem>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</ScrollViewer>
</Page>
Also tried Text="{Binding Annotation, ElementName=page}" and neither works. Output window does not show any binding errors.
@weitzhandler As with other such similar situations, generally the answer as to how to handle this situation currently is to bind to objects that have everything they need accessible from them so you don't need to bind outside of the template.
generally the answer as to how to handle this situation currently is to bind to objects that have everything they need accessible from them so you don't need to bind outside of the template
Of course, and I understand that. But that is not always ideal. And in any case WinUI Binding should not break so many things that worked in WPF, especially not in a non-documented way.
This remains a bug that needs to be fixed.
generally the answer as to how to handle this situation currently is to bind to objects that have everything they need accessible from them so you don't need to bind outside of the template
Of course, and I understand that. But that is not always ideal. And in any case WinUI Binding should not break so many things that worked in WPF, especially not in a non-documented way.
This remains a bug that needs to be fixed.
Hi Weit, I see your comment in Microsoft "For some odd reason after declaring the template as a static resource with a key and referencing it from the control the issue is gone." can you provide an example?
<DataTemplate x:Key="MyTemplate">
<TextBlock Text="{Binding ElementName=ThisPage, Path=viewmodel.Name, Mode=OneWay}" />
</DataTemplate>
<TextBlock
x:Name="Title"
Style="{StaticResource TitleLargeTextBlockStyle}"
Text="{x:Bind viewmodel.Name, Mode=OneWay}" />
<ContentControl ContentTemplate="{StaticResource MyTemplate}" />
I tried this but the ContentControl give me the binding error
Severity Count Data Context Binding Path Target Target Type Description File Line Project
Error 1 power_companies.Features.Campaign.Detail.Page viewmodel.Name Microsoft.UI.Xaml.Controls.TextBlock.Text String BindingExpression path error: 'viewmodel' property not found on 'power_companies.Features.Campaign.Detail.Page'
when the textblock above render out the Name just fine
I should mention that if you want a workaround, you can use Uno's AncestorBinding markup extension.