microsoft-ui-xaml icon indicating copy to clipboard operation
microsoft-ui-xaml copied to clipboard

`x:Load="{x:Bind Blah, Mode=OneWay}"` not working in control template

Open roxk opened this issue 3 years ago • 3 comments

Describe the bug

x:Bind works in control template since 1809. There is a bug however which prevents x:Load from being used with x:Bind. Note that x:Load="False" work, only x:Load={x:Bind Blah, Mode=OneWay} doesn't.

Steps to reproduce the bug

  1. Create a blank app, create the following CustomControlTemplate.xaml and CustomControlTemplate.cs (using user control template -> rename is probably the fastest)
// xaml
<ResourceDictionary
    x:Class="XLoadBindingNotWorkingInTemplate.CustomControlTemplate"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:XLoadBindingNotWorkingInTemplate"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Style TargetType="local:CustomControl" BasedOn="{StaticResource DefaultCustomControlStyke}"/>
    <Style x:Key="DefaultCustomControlStyke" TargetType="local:CustomControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:CustomControl">
                    <TextBlock x:Name="textBlock" Text="{x:Bind Greeting, Mode=OneWay}" x:Load="{x:Bind IsVisible, Mode=OneWay}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
// cs
public sealed partial class CustomControlTemplate : ResourceDictionary
    {
        public CustomControlTemplate()
        {
            this.InitializeComponent();
        }
    }
  1. Add CustomControl that use the style
public sealed class CustomControl : Control, INotifyPropertyChanged
    {
        public CustomControl()
        {
            this.DefaultStyleKey = typeof(CustomControl);
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public bool IsVisible { get; private set; }

        public string Greeting { get { return "Hello world"; } }
        public void MakeVisible()
        {
            IsVisible = true;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsVisible)));
        }
    }
  1. Click run in VS.
  2. Observe doesn't compile with xaml compiler error.
  3. Navigate to obj and find CustomControlTemplate.g.cs, notice 2 compiler errors where obj2 is used without being declared

Expected behavior

x:Load="{x:Bind Blah, Mode=OneWay}" works.

Screenshots

image

NuGet package version

No response

Windows app type

  • [X] UWP
  • [ ] Win32

Device form factor

No response

Windows version

No response

Additional context

  1. This is a WUX issue, but it is likely affecting WinUI 3 as well.
  2. Also reproducible with C++.
  3. The generated code should use dataRoot.GetTemplateChild instead of obj2.FindName.
  4. Minimal repro: https://github.com/roxk/XLoadBindingNotWorkingInTemplateCs

roxk avatar May 11 '22 14:05 roxk

As a workaround, write x:Load="False" and manually call GetTemplateChild(elementName).

roxk avatar May 11 '22 14:05 roxk

Still an issue in WinUI3 with WASDK 1.8

HO-COOH avatar Dec 01 '25 17:12 HO-COOH

As a workaround, write x:Load="False" and manually call GetTemplateChild(elementName).

This is not really a workaround. Unloading a control that is loaded in code-behind could be tricky.

HO-COOH avatar Dec 01 '25 17:12 HO-COOH