我正在编写 WinUI 3 和 UWP 代码,并且我想要一个带有 DependencyProperty 的自定义控件:
<local:MyControl Foo="Bar" />
我已经阅读了 MSDN 上的自定义依赖属性,但是那里有很多内容。使用 C++/WinRT 在 UWP 或 WinUI XAML 中实现自定义 DependencyProperty 所需的最低限度的简短示例是什么?
这是我对自定义依赖属性的提炼,无论如何它都值得一读,因为它解释了依赖属性的许多细微差别:
FooProperty
类型为 static Microsoft.UI.Xaml.DependencyProperty
Foo
的 getter 和 setter。// MyControl.idl
runtimeclass MyControl : Microsoft.UI.Xaml.Controls.UserControl
{
MyControl(); // ... etc
// Add these for each property
static Microsoft.UI.Xaml.DependencyProperty FooProperty{ get; };
String Foo;
}
DependencyObject::GetValue
和 SetValue
实现成员 getter 和 setter(应通过 UserControl 等继承)。Register
您的依赖属性。// MyControl.h
namespace winrt::MyAppNamespace::implementation
{
struct MyControl : MyControlT<MyControl>
{
// ...
static winrt::Microsoft::UI::Xaml::DependencyProperty FooProperty() const noexcept
{
return s_FooProperty;
}
auto Foo() const noexcept
{
return winrt::unbox_value<winrt::hstring>(GetValue(FooProperty()));
}
void Foo(winrt::hstring const& value)
{
SetValue(FooProperty(), winrt::box_value(value));
}
private:
static winrt::Microsoft::UI::Xaml::DependencyProperty s_FooProperty;
}
}
// MyControl.cpp
using namespace winrt::MyAppNamespace::implementation;
MyControl::s_FooProperty =
winrt::Microsoft::UI::Xaml::DependencyProperty::Register(
L"Foo",
winrt::xaml_typename<winrt::hstring>(),
winrt::xaml_typename<winrt::MyAppNamespace::MyControl>(),
winrt::Microsoft::UI::Xaml::PropertyMetadata{nullptr});
完成!您现在拥有一个有效的依赖属性:
<MyControl Foo="Bar!" />
PropertyMetadata
构造函数添加第二个参数。// Value-changed callback
MyControl::s_FooProperty =
winrt::Microsoft::UI::Xaml::DependencyProperty::Register(
L"Foo",
winrt::xaml_typename<winrt::hstring>(),
winrt::xaml_typename<winrt::MyAppNamespace::MyControl>(),
winrt::Microsoft::UI::Xaml::PropertyMetadata{nullptr, &MyControl::OnFooChanged});
// Value-changed callback & default value
MyControl::s_FooProperty =
winrt::Microsoft::UI::Xaml::DependencyProperty::Register(
L"Foo",
winrt::xaml_typename<winrt::hstring>(),
winrt::xaml_typename<winrt::MyAppNamespace::MyControl>(),
winrt::Microsoft::UI::Xaml::PropertyMetadata{winrt::box_value(L"Default value"), &MyControl::OnFooChanged});
注意回调是静态的,而不是成员函数。您必须获取实际实例:
/*static*/ void MyControl::OnFooChanged(winrt::Microsoft::UI::Xaml::DependencyObject const& d, winrt::Microsoft::UI::Xaml::DependencyPropertyChangedEventArgs const& e)
{
auto control{ d.as<MyAppNamespace::MyControl>() };
auto newValue{ winrt::unbox_value<winrt::hstring>(e.NewValue()) };
}