You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C++/WinRT UWP应用中OnLaunched方法内初始化控件的问题咨询

C++/WinRT UWP应用中OnLaunched方法内初始化控件的问题咨询

嘿,我来帮你拆解这个问题!你遇到的情况其实是C++/WinRT中应用类(App)和页面类(MainPage)之间的边界与访问权限问题,咱们一步步来解决你的两个疑问:

第一个问题:如何让编译器在App.cpp中识别myButton?

首先得搞清楚核心原因:myButtonMainPage类的私有成员变量(XAML编译器自动生成的,默认访问权限是private),它属于MainPage的实例,而不是全局变量或者App类的成员。哪怕你在App.cpp里包含了MainPage.g.cpp,也只能看到MainPage类的定义,没法直接访问它的私有成员。

如果一定要在OnLaunched里操作这个按钮,有两个可行的思路:

  1. 给MainPage添加公共接口(推荐)
    这是更符合面向对象设计的做法,不要直接暴露控件,而是在MainPage里写一个公共方法来设置按钮内容:
    • 打开MainPage.h,添加一个公共成员函数:
      void SetButtonContent(winrt::hstring const& content);
      
    • 然后在MainPage.cpp里实现这个方法:
      void MainPage::SetButtonContent(winrt::hstring const& content)
      {
          myButton().Content(winrt::box_value(content));
      }
      
    • 最后在App.cpp的OnLaunched方法里,获取MainPage实例并调用这个方法:
      void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs const& e)
      {
          auto window = Windows::UI::Xaml::Window::Current();
          if (!window.Content())
          {
              window.Content(winrt::make<MainPage>());
          }
          // 获取MainPage实例
          auto mainPage = window.Content().as<MainPage>();
          if (mainPage)
          {
              mainPage.SetButtonContent(L"Clicked");
          }
          window.Activate();
      }
      
  2. 修改myButton的访问权限(不推荐)
    你可以打开MainPage.idl(C++/WinRT项目里会自动生成这个文件),找到myButton的定义,把它的访问修饰符从private改成public。这样App.cpp里拿到MainPage实例后,就可以直接调用mainPage.myButton().Content(...)。但这种做法会破坏封装性,以后维护起来很麻烦,所以非常不推荐。

第二个问题:有没有其他方式初始化控件(不直接访问myButton)?

当然有!而且这才是UWP应用更推荐的初始化方式,完全不需要从App类里操作页面控件:

  1. 在MainPage的构造函数里初始化
    这是最简单的方式,MainPage的构造函数里可以直接访问所有内部控件,你可以在这里设置初始内容,甚至可以读取用户设置后再动态设置:
    MainPage::MainPage()
    {
        InitializeComponent();
        // 在这里直接设置按钮初始内容
        myButton().Content(winrt::box_value(L"Clicked"));
    }
    
  2. 利用页面的Loaded事件
    如果你的初始化需要依赖页面完全加载完成(比如要获取控件的实际尺寸等),可以在MainPage的构造函数里注册Loaded事件:
    MainPage::MainPage()
    {
        InitializeComponent();
        this->Loaded([this](auto&&, auto&&)
        {
            myButton().Content(winrt::box_value(L"Clicked"));
        });
    }
    
  3. 使用数据绑定(MVVM模式,推荐)
    这是UWP官方最推荐的做法,把UI和业务逻辑解耦:
    • 创建一个视图模型类,包含一个ButtonContent属性;
    • 在MainPage.xaml里把按钮的Content属性绑定到这个视图模型的ButtonContent
    • 不管是在App的OnLaunched里还是MainPage的构造函数里,只要更新视图模型的ButtonContent值,按钮内容就会自动更新。这种方式完全不需要直接操作控件,代码可维护性极高。

最后补充一句:你之前尝试包含MainPage.g.cpp没用的原因是,这个文件是XAML编译器生成的MainPage实现文件,里面的myButton是MainPage的私有成员,只有MainPage的内部成员函数才能直接访问,App类的代码不在它的作用域里,所以哪怕包含了也访问不到哦。

内容来源于stack exchange

火山引擎 最新活动