{CustomResource}

问题描述 投票:0回答:1

在 C++ WinUI3 应用程序中 进行数据绑定 时(感谢 SimonMourier 的 demo,我学到了一些知识),我也在查看 {CustomResource} 数据绑定方法。

我创建 WinUI 打包项目

在 MainWindow.xaml 中我放置:

<TextBlock   Text="{CustomResource Test1}"></TextBlock>

我将创建

winrt::Microsoft::UI::Xaml::Resources::CustomXamlResourceLoader
的后代:

class CLX : public winrt::Microsoft::UI::Xaml::Resources::CustomXamlResourceLoader
{
    winrt::Windows::Foundation::IInspectable GetResource(const winrt::param::hstring& resourceId, const winrt::param::hstring& objectType, const winrt::param::hstring& propertyName, const winrt::param::hstring& propertyType) const 
    {
        return winrt::box_value(L"hello");
    }
};

在实现中我会添加一个变量:

CLX clx;

应用程序运行时,我收到预期的异常:

Exception thrown at 0x00007FFE9E97567C (KernelBase.dll) in app1.exe: WinRT originate error - 0x80004005 : 'No custom resource loader set.'.
Microsoft.UI.Xaml.dll!00007FFE3F265DD3: 80004005 - Unspecified error
Exception thrown at 0x00007FFE9E97567C (KernelBase.dll) in app1.exe: WinRT originate error - 0x802B000A : 'No custom resource loader set. [Line: 12 Position: 22]'.

现在,在 OnLaunched() 中:

winrt::Microsoft::UI::Xaml::Resources::CustomXamlResourceLoader::Current(clx);

这会导致不同的异常:

Exception thrown at 0x00007FFE9E97567C (KernelBase.dll) in app1.exe: WinRT originate error - 0x802B000A : 'Markup extension could not provide value. [Line: 12 Position: 22]'.

所以它看到了该处理程序,因为它似乎尝试调用它,但那里的断点没有命中也不能放置。该函数似乎从未被编译过。这不是很奇怪吗,这不是运行时功能吗?

我的 GetResource() 实现正确吗? 我不知道从现在开始该怎么办。

c++ xaml winui-3 c++-winrt
1个回答
0
投票

虽然这在编译时有效:

class CLX : public winrt::Microsoft::UI::Xaml::Resources::CustomXamlResourceLoader
{
    winrt::Windows::Foundation::IInspectable GetResource(const winrt::param::hstring& resourceId, const winrt::param::hstring& objectType, const winrt::param::hstring& propertyName, const winrt::param::hstring& propertyType) const 
    {
        return winrt::box_value(L"hello");
    }
};

GetResource
方法不会被调用,因为它“只是”一个 C++ 方法,而内置
CustomXamlResourceLoader
将此方法实现为
ICustomXamlResourceLoaderOverrides
COM 接口的方法。

C++/WinRT 为所有 WinRT 类型提供了一个名为

[Type]T
的实用程序类来包装所有这些 COM 管道,因此如果您像这样声明它,它将起作用:

struct CLX : winrt::Microsoft::UI::Xaml::Resources::CustomXamlResourceLoaderT<CLX>
{
  IInspectable GetResource(const hstring& resourceId, const hstring& objectType, const hstring& propertyName, const hstring& propertyType) const
  {
    return winrt::box_value(L"hello");
  }
};

并像这样实例化:

void App::OnLaunched([[maybe_unused]] LaunchActivatedEventArgs const& e)
{
    auto clx = make<CLX>();
    winrt::Microsoft::UI::Xaml::Resources::CustomXamlResourceLoader::Current(clx);
    ...
}
© www.soinside.com 2019 - 2024. All rights reserved.