Search code examples
c#wpfwinui-3winuiwindows-community-toolkit

CommunityToolkit.WinUI.Converters don't work as per documentation


Continuing my saga in WPF to WinUI migration (part 1 can be viewed here). Because I'm already using the Community Toolkit for MVVM I'm using some of the other offerings there as well.

I tried, rather than my old approach of using a custom converter, using the ones found in CommunityToolkit.WinUI.Converters. The documentation says that it's as simple as 1-2-3

  1. Add the namespace
xmlns:converters="using:CommunityToolkit.WinUI.Converters"
  1. Add the resource
<Page.Resources>
   <converters:StringFormatConverter x:Key="StringFormatConverter"/>
</Page.Resources>
  1. Call it from your XAML
<TextBlock Text="{x:Bind viewModel.SelectedWorkbook.CountOfWorksheets, Mode=OneWay, Converter={StaticResource StringFormatConverter}, ConverterParameter='{}Count of worksheets: {0}'}"/>

But this fails at build time with an error like follows:

CS1503  Argument 1: cannot convert from 'Company.Dept.App.Views.MainWindow' to 'Microsoft.UI.Xaml.FrameworkElement'

This is a normal C# error like what you'd get when trying to do something assigning a variable of type string to a variable of type integer, but I don't understand why it manifests itself here when using this converter in exactly the way that the documentation prescribes.

Is there a simple fix for this?

** EDIT ** I noticed the documentation has the namespace hanging off a Page element so I changed it to this, but it didn't make a whit of a difference.


Solution

  • Unlike WPF, in WinUI you can't use value converters in the Window class XAML.

    So, the following code:

    <Window
        x:Class="WinUIDemoApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="using:WinUIDemoApp"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid x:Name="RootGrid">
            <Grid.Resources>
                <local:SomeValueConverter x:Key="SomeValueConverter" />
            </Grid.Resources>
            <Button Content="{x:Bind SomeText, Mode=OneWay, Converter={StaticResource SomeValueConverter}}" />
        </Grid>
    
    </Window>
    

    will give you this error:

    CS1503  Argument 1: cannot convert from 'WinUIDemoApp.MainWindow' to 'Microsoft.UI.Xaml.FrameworkElement'
    

    There is an open issue in the WinUI GitHub repo about this.

    So, I recommend using the Window as a wrapper and placing a Page with your contents in it.

    <Window...>
        <local:MainPage />
    </Window>