Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding to own dependency properties is not working #9678

Closed
Woopsalla opened this issue May 27, 2024 · 5 comments
Closed

Binding to own dependency properties is not working #9678

Woopsalla opened this issue May 27, 2024 · 5 comments
Labels
area-Binding bug Something isn't working team-Markup Issue for the Markup team

Comments

@Woopsalla
Copy link

Describe the bug

The attached demo project contains a simple GUI with a button and a derived user control MyUserControl.
MyUserControl only contains a border whose background is bound to the background of the user control:

void MyUserControl::CreateGui()
{
    winrt::Microsoft::UI::Xaml::Controls::Border b;
    Content(b);
    b.BorderThickness(winrt::Microsoft::UI::Xaml::Thickness{ 1, 1, 1, 1 });
    b.BorderBrush(winrt::Microsoft::UI::Xaml::Media::SolidColorBrush(winrt::Windows::UI::Colors::Black()));

    winrt::Microsoft::UI::Xaml::Data::Binding binding;
    binding.Source(*this);
    binding.Path(winrt::Microsoft::UI::Xaml::PropertyPath(L"Background"));
    b.SetBinding(winrt::Microsoft::UI::Xaml::Controls::Border::BackgroundProperty(), binding);
}

MyUserControl also registers its own DependencyProperty AnotherBrush of type Brush:

void MyUserControl::InitClass()
{
    mAnotherBrushProperty =
        Microsoft::UI::Xaml::DependencyProperty::Register(
            L"AnotherBrush",
            winrt::xaml_typename<winrt::Microsoft::UI::Xaml::Media::Brush>(),
            winrt::xaml_typename<winrt::UnpackagedDesktopApp::MyUserControl>(),
            Microsoft::UI::Xaml::PropertyMetadata(nullptr)
        );
}

InitClass is called in App::OnLaunched before MainWindow is created.
When the MainWindow is initialized, the brushes of the MyUserCOntrol instance are set:

mUC = winrt::UnpackagedDesktopApp::MyUserControl();
sp.Children().Append(mUC);
mUC.Width(200);
mUC.Height(100);
mUC.Background(winrt::Microsoft::UI::Xaml::Media::SolidColorBrush(winrt::Windows::UI::Colors::GreenYellow()));
mUC.AnotherBrush(winrt::Microsoft::UI::Xaml::Media::SolidColorBrush(winrt::Windows::UI::Colors::Red()));
mUC.Foreground(winrt::Microsoft::UI::Xaml::Media::SolidColorBrush(winrt::Windows::UI::Colors::CornflowerBlue()));

When the button is pressed, the background of the MyUserControl instance is bound to its own dependency property AnotherBrush:

void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&)
{
    auto checkAnotherBrush = mUC.AnotherBrush();

    winrt::Microsoft::UI::Xaml::Data::Binding binding;
    binding.Source(mUC);
    binding.Path(winrt::Microsoft::UI::Xaml::PropertyPath(L"AnotherBrush")); //doesn't work!!
    //binding.Path(winrt::Microsoft::UI::Xaml::PropertyPath(L"Foreground")); //works
    mUC.SetBinding(winrt::Microsoft::UI::Xaml::Controls::Control::BackgroundProperty(), binding);

    auto checkUCBackground = mUC.Background();

    mBtn.Content(box_value(L"Clicked"));
}

The background of MyUserControl should now have the same color as AnotherBrush (i.e. red). When debugging, you can see from the variable checkAnotherBrush that AnotherBrush is actually set. However, the variable checkUCBackground shows that the background is unexpectedly NULL after the binding has been applied.
However, if the background is bound to the built-in Foreground property instead, it works!
DemoApp.zip

Steps to reproduce the bug

1.Build and run the attached demo app.
2. Click the button.
3. Debug the method MainWindow::myButton_Click.

Expected behavior

Binding should also work for own dependency properties.

Screenshots

No response

NuGet package version

WinUI 3 - Windows App SDK 1.5.3: 1.5.240428000

Windows version

Windows 10 (21H2): Build 19044

Additional context

Microsoft Visual Studio Community 2022 (64-bit) - Current Version 17.10.0

@Woopsalla Woopsalla added the bug Something isn't working label May 27, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issue needs to be triaged by the area owners label May 27, 2024
Copy link

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one. Thank you!

Open similar issues:

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

@Woopsalla
Copy link
Author

Is there any natural intelligence other than AI that can help with this problem? A hint as to the cause of the problem and a possible workaround would help. The demo project is so simple that it is surprising that binding does not work. Maybe someone has a hint on how to further analyze the problem?

@codendone codendone added area-Binding team-Markup Issue for the Markup team and removed needs-triage Issue needs to be triaged by the area owners labels Jun 13, 2024
@evelynwu-msft
Copy link
Contributor

@Woopsalla Because your custom control is neither used in XAML markup nor is its IDL declaration decorated with the [bindable] attribute, XamlCompiler does not know about it and therefore does not generate any type information for it. As a result, from the framework's perspective at run-time there is no type MyUserControl with a property AnotherBrush.

You can resolve this in one of two ways (and be sure to add #include "MyUserControl.h" to App.xaml.h to avoid a build break):

  1. Decorate the declaration of MyUserControl in MyUserControl.idl with a [bindable] attribute
  2. Add an instance of MyUserControl to one of the project's .xaml files.

@Woopsalla
Copy link
Author

Thank you Evelyn Wu for your help. This has solved the problem. Can you recommend any documentation that goes into the subject in more depth? I spent a lot of time looking for a solution and also got suggested solutions elsewhere that actually went in the wrong direction. Perhaps the right reference can shed some light on the subject.

@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issue needs to be triaged by the area owners label Jun 21, 2024
@evelynwu-msft
Copy link
Contributor

@Woopsalla This MSDN article describes in-depth the requirements for different binding scenarios; if you search for BindableAttribute you'll find more information about when it is required. (Even though the article itself is in the context of UWP, the same requirements exist for Windows App SDK; I'm looking into why the Windows App SDK version of the article contains significantly less information in comparison.)

@evelynwu-msft evelynwu-msft removed the needs-triage Issue needs to be triaged by the area owners label Jun 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Binding bug Something isn't working team-Markup Issue for the Markup team
Projects
None yet
Development

No branches or pull requests

3 participants