-1

In Visual Studio I compiled the blank C++/WinRT UWP app which displays a button that says "Click me" and "Clicked" after it is clicked. As an experiment to learn how to initialize a control according to user settings, I copied the following line from ClickHandler in MainPage.cpp

myButton().Content(box_value(L"Clicked"));

and pasted it as the last line of OnLaunched in App.cpp. The idea is that if that works, the application when launched will display "Clicked" in the button even before it is clicked. The problem is, when I try to compile the program, I get

error C3861: 'myButton': identifier not found.

myButton is recognized by the compiler in MainPage.cpp but not in App.cpp. I thought that might be because a header file or a "using namespace" statement needs to be included in App.cpp. To my surprise, the only #include in MainPage.cpp that is not in App.cpp is #include "MainPage.g.cpp", and the two namespace statements, using namespace winrt; and using namespace Windows::UI::Xaml; are both in App.cpp. So, I copied and pasted #include "MainPage.g.cpp" into App.cpp, but the compiler still reports "myButton': identifier not found."

My first question is, how can I make the complier recognize myButton as a valid identifier? My second question is, if there is no way to make the complier recognize myButton, is there any way to initialize a control to anything besides its default condition defined in MainPage.xaml?

2
  • 1
    Can you show your code? It's easier if we can see your code rather than a description of it. See minimal reproducible example. Commented Jun 28 at 0:56
  • This is more of an application/compiler question than a "what is wrong with this line of code" question. The line of code contains a Button name that is recognized in one cpp file but not in another cpp file. The problem could be in any of several cpp, h, and xaml files. All of the source code files can be reproduced in Visual Studio by loading the template for a blank C++/WinRT UWP project. The only modification I made was to copy "myButton().Content(box_value(L"Clicked"));" from ClickHandler in MainPage.cpp and paste it into the last line of OnLaunched in App.cpp. Commented Jun 28 at 4:35

2 Answers 2

1

The expression myButton() is short for this->myButton(). When you moved the expression from MainPage::ClickHandler() to App::OnLaunched(), you've unwittingly changed what this refers to, from MainPage* to App*. While MainPage defines a class member called myButton (see "Generated Files\MainPage.xaml.g.h"), App does not, and the compiler rightfully complains.

Changing a property of a control necessitates that it is accessible. While the (generated) myButton() accessor is a public class member of MainPage and is thus visible to the outside world, keeping the code in MainPage's implementation is easier to understand and maintain.

Beyond that, there's also the run-time requirement for the XAML UI to be in a sufficiently complete state so that accessing controls is well defined. The Loaded event (inherited from Windows.UI.Xaml.FrameworkElement) is raised when the UI has reached that stage, and we can subscribe to it:

MainPage.xaml

<Page ...
      Loaded="OnLoaded">
...

MainPage.h

struct MainPage : MainPageT<MainPage>
{
    // ...

    void OnLoaded(Windows::Foundation::IInspectable const&,
                  Windows::UI::Xaml::RoutedEventArgs const&)
    {
        myButton().Content(box_value(L"OnLoaded"));
    }
};

Note: I put the implementation in the header file to keep the code concise. You can move it to the corresponding .cpp file if you want. It doesn't make a difference.

The above illustrates how to update a control's properties at run-time. There isn't anything wrong with doing this; however, it does scale poorly as the UI grows in complexity. To keep that under control, the XAML framework offers an elaborate data binding system.

It is non-trivial to set up, though, so I won't be covering it here.

Sign up to request clarification or add additional context in comments.

Comments

0

Opening MainPage in Designer and adding a handler for the Loading event of the button solved the problem. The initialization of the button can be done in the handler.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.