microsoft-ui-xaml
microsoft-ui-xaml copied to clipboard
Can't use x:Bind with Converter in Window
Describe the bug
Hi, I've tried to use the x:Bind with IValueConverter. But the project doesn't compile - CS1503 Argument 1: cannot convert from 'TestApp.MainWindow' to 'Microsoft.UI.Xaml.FrameworkElement'. Please take a look at the following code. What I do wrong?
Steps to reproduce the bug
<Window
x:Class="TestApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid RowDefinitions="Auto, *" x:Name="root">
<Grid.Resources>
<local:MyConverter x:Key="MyConverter"/>
</Grid.Resources>
<StackPanel Spacing="12"
Grid.Row="1">
<TextBlock Text="{x:Bind MyProperty, Converter={StaticResource MyConverter}}"/>
</StackPanel>
</Grid>
</Window>
public class MyConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, string language) => value;
public object ConvertBack(object value, Type targetType, object parameter, string language) => value;
}
public sealed partial class MainWindow : Window {
public MainWindow() {
this.InitializeComponent();
}
public string MyProperty { get; } = "Test";
Expected behavior
Screenshots

Version Info
NuGet package version:
[WinUI 3 - Project Reunion 0.5: 0.5.6]
Windows app type:
| UWP | Win32 |
|---|---|
| Yes |
| Windows 10 version | Saw the problem? |
|---|---|
| Insider Build (xxxxx) | |
| October 2020 Update (19042) | Yes |
| May 2020 Update (19041) | |
| November 2019 Update (18363) | |
| May 2019 Update (18362) | |
| October 2018 Update (17763) | |
| April 2018 Update (17134) | |
| Fall Creators Update (16299) | |
| Creators Update (15063) |
| Device form factor | Saw the problem? |
|---|---|
| Desktop | Yes |
| Xbox | |
| Surface Hub | |
| IoT |
Additional context
@RealTommyKlein FYI
Thanks for the report. The root of your .xaml needs to be a FrameworkElement since the Xaml compiler expects to be able to use the FrameworkElement.Resources property to get its resource dictionary. Since Window isn't a FrameworkElement, the generated code breaks down.
Instead, you should move the UI logic (<Grid RowDefinitions="Auto, *" x:Name="root"> etc.) into its own UserControl, and then set that UserControl as the content of the Window.
Yeah, I too keep getting tripped up that Window isn't a DependencyObject... it's a bit weird.
If the expectation that Window is supposed to just be the host like the implicit Frame created in App.xaml.cs for UWP apps, maybe the File -> New template for WinUI 3 should separate out the MainWindow as also having a MainPage class hosted by it already setup?
This would help lead developers to the proper constructs when building their app and set them up for success vs. having everyone start dumping UI in MainWindow and then getting frustrated.
I mean I really like how the MainWindow is more exposed compared to all the extra logic on Startup that was done in the UWP space, but it's super confusing and bare-bones template when trying to start building an app from afterwards without creating a new Page first.
This would help lead developers to the proper constructs when building their app and set them up for success vs. having everyone start dumping UI in
MainWindowand then getting frustrated.I mean I really like how the
MainWindowis more exposed compared to all the extra logic on Startup that was done in the UWP space, but it's super confusing and bare-bones template when trying to start building an app from afterwards without creating a newPagefirst.
But we have another problem: CustomTitleBar we can set only with XAML code in MainWindow.xaml, yes? Using other UI in other page.xaml file will say No for united title with UI.
Best issue about i want to say #2124 with a lot of scrennsots
Coming from a strictly WPF/.NET Framework background, and trying out WinUI 3.x for the first time... this is really non-intuitive, especially when trying to port multi-window applications.
I realize that there is a fundamental difference in how UWP apps behave versus how traditional multi-window applications behave, but there should be an elegant solution to this problem nonetheless.
Thanks for the report. The root of your
.xamlneeds to be aFrameworkElementsince the Xaml compiler expects to be able to use theFrameworkElement.Resourcesproperty to get its resource dictionary. SinceWindowisn't aFrameworkElement, the generated code breaks down.Instead, you should move the UI logic (
<Grid RowDefinitions="Auto, *" x:Name="root">etc.) into its ownUserControl, and then set thatUserControlas the content of theWindow.
Thanks for the report. The root of your
.xamlneeds to be aFrameworkElementsince the Xaml compiler expects to be able to use theFrameworkElement.Resourcesproperty to get its resource dictionary. SinceWindowisn't aFrameworkElement, the generated code breaks down.Instead, you should move the UI logic (
<Grid RowDefinitions="Auto, *" x:Name="root">etc.) into its ownUserControl, and then set thatUserControlas the content of theWindow.
Isn't the Grid the root element ? the converter is defined in grid resources
Can a sample / example be provided in WinUI docs (if recommendation is to restructure the xaml to expose a usercontrol in order to use a converter / static resource?) so people don't spend cycles figuring out why this simple thing is not working. I am trying to use a boolean to visibility converter and it is so time consuming this simple thing.
Can a sample / example be provided in WinUI docs
@gabbybilka
Thanks for the report. The root of your
.xamlneeds to be aFrameworkElementsince the Xaml compiler expects to be able to use theFrameworkElement.Resourcesproperty to get its resource dictionary. SinceWindowisn't aFrameworkElement, the generated code breaks down. Instead, you should move the UI logic (<Grid RowDefinitions="Auto, *" x:Name="root">etc.) into its ownUserControl, and then set thatUserControlas the content of theWindow.Thanks for the report. The root of your
.xamlneeds to be aFrameworkElementsince the Xaml compiler expects to be able to use theFrameworkElement.Resourcesproperty to get its resource dictionary. SinceWindowisn't aFrameworkElement, the generated code breaks down. Instead, you should move the UI logic (<Grid RowDefinitions="Auto, *" x:Name="root">etc.) into its ownUserControl, and then set thatUserControlas the content of theWindow.Isn't the Grid the root element ? the converter is defined in grid resources
I think this is a worthwhile point. The auto-gen code successfully finds a Grid at the element where the resource is placed. It then passes '*this' (which is the Window) to SetConverterLookupRoot. When it could just set it as the target.as<Grid> that it's using for the SetDataRoot call. It's not a documentation issue. It's a autogen code issue with an inconsistent use of the term 'root' in the code block. e.g.:
case 3: // MainWindow.xaml line 45
{
auto element3 = target.as<::winrt::Microsoft::UI::Xaml::Controls::Grid>();
auto objBindings = std::make_unique<MainWindow_obj3_Bindings>();
objBindings->SetDataRoot(element3.DataContext()); // Here we are using the frameworkElement we found correctly as the 'dataRoot'
objBindings->SetConverterLookupRoot(*this); // Here we are inconsistently reverting to making the ConverterLookupRoot use *this, which is the Window
Refactoring code to avoid this autogen issue or making it about documentation seems like it's not very customer-focused. Why do we need to read more and refactor code, when this seems like a minor, and easily changeable portion of the generated code?
This is a bug in autogenerated code, of course, not a documentation issue. No one in their right mind creates a separate control for every page.
I would even say that it is a critical bug which requires few hours to fix it, but due to the fact that tags assigned to the task are misleading, I guess it will not be fixed until 2030.
This is a big problem, how did you remove the ease of functionality that was binding in WPF/UWP and replace it with this?? I'm trying to use a boolean to visibility converter in my current project and cannot get it to work: Argument 1: cannot convert from 'Demo.MainWindow' to 'Microsoft.UI.Xaml.FrameworkElement' even though my converter and control is part of a Grid element. I'm definitely not going to make some custom UserControl as a work-around to this issue (that never was an issue before), it needs to be addressed ASAP! Are you trying to make the framework more difficult or less difficult? I understand that you're trying to abstract away the Window from the framework, but in doing that you need to provide basic functions... like WindowResize, WindowCenter, WindowMove, etc.
This is definitely a problem. Why must I create a FrameworkElement instead of a Window?
Since this is still not working, is there any plan to address this? Apart from this not being mentioned anywhere except for these bug reports, this is insanely impractical and the mentioned workaround is nothing short of a hack...
Hello Guys, Any plan to solve this issue ?
@Reza-Noei Unfortunately I don't think MS views this as a problem, and there will never be a "fix" since they have abstracted the Window object away from the Microsoft.UI.Xaml.FrameworkElement. I would suggest just using the MainWindow as a wrapper for a Frame/Page and then proceed as usual from there.
@GuildOfCalamity ty for the answer. Sad for Microsoft 😢. So they should remove it from the WinUI-3's Template Studio. That's so ridiculous 🤦♂️
@RealTommyKlein
The work around suggests using a UserControl but I need to use a bool to vis converter in the TitleBar
The TitleBar cant take a UserControl so how can we do this?
The more familiar you are with WPF, the more confused you will be. Even if the error is due to a different base architecture, this error message gives no information for a solution. I finally managed to get to the information here from the vast web, but those who can't get to it are leaving WinUI3. This is very problematic.
This is very unintuitive for anyone familiar with WPF. One option is to use traditional binding when a converter is required.
<Grid x:Name="Root">
<TextBlock Text="{Binding Text, Converter={StaticResource MyConverter}}"/>
</Grid>
// Code Behind
Root.DataContext = vm;
++ To all this. I am having this problem as well. It seems like both the generated code and the default template should be fixed.