For example, there is ItemsSource property in ItemsControl, declared in C++/WinRT :
IInspectable ItemsSource();
void ItemsSource(IInspectable value);
//The type of the object that you set the ItemsSource property to must implement one of these interfaces: IVector<IInspectable>, IBindableObservableVector etc.
Usually, it can be setup by C++/WinRT vector like:
control.ItemsSource(winrt::single_threaded_vector<winrt::hstring>(…))
Based on The Browser Company’s swift-winrt tools, its projections like:
public var itemsSource : Any! {
get { try! _default.get_ItemsSource() }
set { try! _default.put_ItemsSource(newValue) }
}
But how to pass parameter of collection types into?
control.itemsSource = Array<String>[...].toVector() // Crash, not working
Any help or hint is really appreciated, thank you !
Thanks to Mr.Saleem's "Interoperability: Swift's Super Power" and the old but still vary valuable book "Essential COM" from Mr.Don Box. Finally it works.
In summary:
-
Didn't find any exsiting WinRT object implements both IInspectable and IVector, which is required by ItemsSource API. So that no swift projection class can be used directly;
-
Swift can't build as COM object yet. Hope it can do in future;
-
So need to create the COM object in C/C++, then wrapper with Swift, and set the property.
For example, in C++ :
::IInspectable * CreateIVector()
{
auto vec = winrt::single_threaded_vector<winrt::Windows::Foundation::IInspectable>();
vec.Append(winrt::box_value(L"Test"));
vec.Append(winrt::box_value(L"Test2"));
vec.Append(winrt::box_value(L"Test3"));
auto inspectable_vec = vec.as<::IInspectable>();
auto *raw_inspectable_ptr = inspectable_vec.get();
raw_inspectable_ptr->AddRef();
return raw_inspectable_ptr;
}
Then in Swift, based on swift-winrt of TBC :
let (com) = ComPtrs.initialize { abi in
abi = CreateIVector()
}
let insp = WindowsFoundation.IInspectable(com!)
bread.itemsSource = insp
Hope above is useful for other people interested in Swift WinUI.
2 Likes