Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Tavsiye
Bu konuyu daha önce okuduysanız ve belirli bir görevi göz önünde bulundurarak bu konuya geri dönüyorsanız, bu konunun gerçekleştirdiğiniz göreve göre içerik bul
Bu konu, bir C# projesindeki kaynak kodu C++/WinRTeşdeğerine taşımayla ilgili teknik ayrıntıları kapsamlı bir şekilde kataloglar.
Evrensel Windows Platformu (UWP) uygulama örneklerinden birini taşımaya yönelik bir örnek olay incelemesi için, Pano örneğini C#'den C++/WinRT'ye taşıma
Nasıl hazırlanır ve ne bekleyebileceğiniz
Örnek olay Pano örneğini C# C++/WinRT'ye taşıma işlemi, bir projeyi C++/WinRT'ye taşırken yapacağınız yazılım tasarımı kararlarının örneklerini göstermektedir. Bu nedenle, mevcut kodun nasıl çalıştığı hakkında sağlam bir anlayış elde ederek taşımaya hazırlanmak iyi bir fikirdir. Bu şekilde, uygulamanın işlevselliğine ve kodun yapısına iyi bir genel bakış elde edersiniz ve ardından alacağınız kararlar sizi her zaman ileriye ve doğru yöne götürür.
Ne tür taşıma değişiklikleri bekleyebileceğinize göre, bunları dört kategoride gruplandırabilirsiniz.
-
Dil projeksiyonunu. Windows Çalışma Zamanı (WinRT) çeşitli programlama dillerine yansıtılmaktadır. Bu dil yansıtmasının her biri, söz konusu programlama diline göre doğal bir his verecek şekilde tasarlanmıştır. C# için, bazı Windows Çalışma Zamanı türleri .NET türleri olarak yansıtılır. Örneğin, System.Collections.Generic.IReadOnlyList<T> ifadesini Windows.Foundation.Collections.IVectorView<T>ifadesine geri çevireceksiniz. Ayrıca C# dilinde bazı Windows Çalışma Zamanı işlemleri uygun C# dil özellikleri olarak yansıtılır. C# dilinde olay işleme temsilcisini kaydetmek için
+=işleci söz dizimini kullanmanız buna örnek olarak verilmiştir. Bu nedenle, bunun gibi dil özelliklerini gerçekleştirilmekte olan temel işleme (bu örnekte olay kaydı) çevireceksiniz. -
Bağlantı noktası dili söz dizimi. Bu değişikliklerin çoğu basit mekanik dönüşümlerdir ve bir simgeyi başka bir simgeyle değiştirir. Örneğin, nokta (
.) işaretini iki nokta üst üste (::) olarak değiştirmek. -
Bağlantı noktası dil yordamı. Bunlardan bazıları basit, yinelenen değişiklikler (
myObject.MyPropertymyObject.MyProperty()gibi) olabilir. Bazıları daha derin değişiklikler gerektirir (örneğin, System.Text.StringBuilder kullanımını içeren bir işlemin std::wostringstreamkullanılmasını içeren bir işleme dönüştürülmesi gerekir). -
C++/WinRT'e özgü port etme ile ilgili görevler. Windows Çalışma Zamanı'nın bazı ayrıntıları, arka planda C# tarafından örtük olarak ele alınır. Bu ayrıntılar C++/WinRT'de açıkça yapılır. Çalışma zamanı sınıflarınızı tanımlamak için bir
.idldosyası kullanmanız buna örnek olarak verilmiştir.
Sonraki görev tabanlı dizinden sonra, bu konudaki bölümlerin geri kalanı yukarıdaki taksonomiye göre yapılandırılır.
Gerçekleştirmekte olduğunuz göreve göre içerik bulma
| Görev | İçerik |
|---|---|
| Windows Çalışma Zamanı bileşeni (WRC) oluşturma | Belirli işlevler yalnızca C++ ile gerçekleştirilebilir (veya belirli API'ler çağrılabilir). Bu işlevi bir C++/WinRT WRC olarak hesaba katabilir ve ardından WRC'yi bir C# uygulamasından (örneğin) kullanabilirsiniz. Bkz. C++/WinRT ile Windows Çalışma Zamanı bileşenlerini |
| Zaman uyumsuz bir yöntemi porta etmek | C++/WinRT çalışma zamanı sınıfındaki zaman uyumsuz bir yöntemin ilk satırının Task'den taşıma, bkz. Asenkron eylem.Task<T>'den taşıma için bkz. Asenkron işlem.async void'den taşıma, bkz. , Fire-and-forget yöntemi. |
| Bir sınıfı aktarma | İlk olarak, sınıfın çalışma zamanı sınıfı olması gerekip gerekmediğini veya sıradan bir sınıf olup olmadığını belirleyin. Buna karar vermenize yardımcı olmak için C++/WinRTile |
| Çalışma zamanı sınıfını aktarma | C++ uygulamasının dışındaki işlevleri paylaşan bir sınıf veya XAML veri bağlamasında kullanılan bir sınıf. Bir Windows Çalışma Zamanı bileşeninde çalışma zamanı sınıfı yazıyorsanız bkz. veya XAML kullanıcı arabiriminizde başvurulacak bir çalışma zamanı sınıfı yazıyorsanız bkz. . Bu bağlantılar bunu daha ayrıntılı olarak açıklar, ancak idl'de bir çalışma zamanı sınıfı bildirilmelidir. Projeniz zaten bir IDL dosyası içeriyorsa (örneğin, Project.idl), bu dosyada yeni bir çalışma zamanı sınıfı bildirmenizi öneririz. IDL'de, uygulamanızın dışında veya XAML'de kullanılacak tüm yöntemleri ve veri üyelerini bildirin. IDL dosyasını güncelleştirdikten sonra, projenizin |
| Sıradan bir sınıfı taşıma | Bkz. Eğer bir çalışma zamanı sınıfı yazmıyorsanız. |
| Yazar IDL |
Microsoft Arabirim Tanımı Dili 3.0 Giriş XAML kullanıcı arabiriminizde başvurulacak bir çalışma zamanı sınıfı yazıyorsanız XAML işaretlemesinden nesne tüketme Çalışma zamanı sınıflarınızı IDL'de tanımlayın |
| Koleksiyonu taşıma |
C++/WinRT ile Koleksiyonlar XAML işaretlemeye bir veri kaynağı kullanılabilir hale getirme İlişkili kapsayıcı Vektör üyesi erişimi |
| Bir olayı aktarmak |
Sınıf üyesi olarak olay işleyici temsilcisi Olay işleyici temsilcisini iptal etme |
| Bir yöntemi taşıma | C#'den: private async void SampleButton_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e) { ... }C++/WinRT .h dosyasına: fire_and_forget SampleButton_Tapped(IInspectable const&, RoutedEventArgs const&);C++/WinRT .cpp dosyasına: fire_and_forget OcrFileImage::SampleButton_Tapped(IInspectable const&, RoutedEventArgs const&) {...} |
| Bağlantı noktası dizeleri |
C++/WinRT'de Dize İşleme ToString Dize oluşturma Bir dizeyi kutulama ve açık kutulama |
| Tür dönüştürme (tür atama) | C#: o.ToString()C++/WinRT: to_hstring(static_cast<int>(o))Ayrıca bkz. ToString. C#: (Value)oC++/WinRT: unbox_value<Value>(o)Kutu açma başarısız olursa atar. Ayrıca bkz. Boxing ve unboxing. C#: o as Value? ?? fallbackC++/WinRT: unbox_value_or<Value>(o, fallback)Kutu açma başarısız olursa geri dönüş döndürür. Ayrıca bkz. Boxing ve unboxing. C#: (Class)oC++/WinRT: o.as<Class>()Dönüştürme başarısız olursa atar. C#: o as ClassC++/WinRT: o.try_as<Class>()Dönüştürme başarısız olursa null döndürür. |
Dil projeksiyonunu içeren değişiklikler
| Kategori | C# (programlama dili) | C++/WinRT | Ayrıca bakınız |
|---|---|---|---|
| Yazılmamış nesne |
objectveya System.Object |
Windows::Foundation::IInspectable | EnableClipboardContentChangedNotifications yöntemini taşımak |
| Projeksiyon ad alanları | using System; |
using namespace Windows::Foundation; |
|
using System.Collections.Generic; |
using namespace Windows::Foundation::Collections; |
||
| Koleksiyonun boyutu | collection.Count |
collection.Size() |
BuildClipboardFormatsOutputString yönteminin taşınması |
| Tipik koleksiyon türü | IList<T>ve bir öğe eklemek için Ekle. | IVector<T>ve bir öğe eklemek için Ekleyin. std::vector'ü herhangi bir yerde kullanıyorsanız, ardından bir öğe eklemek için push_back kullanın. | |
| Salt okunur koleksiyon türü | IReadOnlyList<T> | IVectorView<T> | BuildClipboardFormatsOutputString yönteminin taşınması |
| Sınıf üyesi olarak olay işleyicisi temsilcisi | myObject.EventName += Handler; |
token = myObject.EventName({ get_weak(), &Class::Handler }); |
EnableClipboardContentChangedNotifications yöntemini taşımak |
| Etkinlik işleyici temsilcisini geri almak | myObject.EventName -= Handler; |
myObject.EventName(token); |
EnableClipboardContentChangedNotifications yöntemini taşımak |
| İlişkili kapsayıcı | IDictionary<K, V> | IMap<K, V> | |
| Vektör üyesine erişim | x = v[i];v[i] = x; |
x = v.GetAt(i);v.SetAt(i, x); |
Olay işleyicisini kaydetme/iptal etme
C++/WinRT'de, C++/WinRT'de temsilcileri kullanarak olayları işleme
Bazen, örneğin bir olay alıcısı (olayı işleyen bir nesne) yok edilmek üzere olduğunda, olay kaynağının (olayı oluşturan nesne) yok edilmiş bir nesneye çağrı yapmaması için bir olay işleyicisini iptal etmek istersiniz. Bkz. Kayıtlı temsilciyi geri çekme. Böyle durumlarda, olay işleyicileriniz için bir event_token üye değişkeni oluşturun. Örnek için bkz. EnableClipboardContentChangedNotifications yönteminitaşıma.
XAML işaretlemesinde bir olay işleyicisi de kaydedebilirsiniz.
<Button x:Name="OpenButton" Click="OpenButton_Click" />
C# dilinde, OpenButton_Click yönteminiz özel olabilir ve XAML bunu ButtonBase'e bağlamaya devam edebilir.OpenButtontarafından tetiklenen olayına tıklayın.
C++/WinRT'de,
namespace winrt::MyProject::implementation
{
struct MyPage : MyPageT<MyPage>
{
void OpenButton_Click(
winrt::Windows:Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::RoutedEventArgs const& args);
}
};
Alternatif olarak, XAML kayıt sayfasını uygulama türünüzle dost haline getirebilir ve OpenButton_Click öğesini özel yapabilirsiniz.
namespace winrt::MyProject::implementation
{
struct MyPage : MyPageT<MyPage>
{
private:
friend MyPageT;
void OpenButton_Click(
winrt::Windows:Foundation::IInspectable const& sender,
winrt::Windows::UI::Xaml::RoutedEventArgs const& args);
}
};
Son senaryolardan biri, taşıma
<Button x:Name="OpenButton" Click="{x:Bind OpenButton_Click}" />
Bu işaretlemeyi daha basit Click="OpenButton_Click"olarak değiştirebilirsiniz. Tercih ederseniz, işaretlemeyi olduğu gibi tutabilirsiniz. Bunu desteklemek için yapmanız gereken tek şey IDL'de olay işleyicisini bildirmektir.
void OpenButton_Click(Object sender, Windows.UI.Xaml.RoutedEventArgs e);
Dil söz dizimini içeren değişiklikler
| Kategori | C# (programlama dili) | C++/WinRT | Ayrıca bakınız |
|---|---|---|---|
| Erişim değiştiricileri | public \<member\> |
public:\<member\> |
Button_Click yöntemini taşıma |
| Veri üyesine erişme | this.variable |
this->variable |
|
| Asenkron eylem | async Task ... |
IAsyncAction ... |
IAsyncAction arabirimi, C++/WinRT ile Eşzamanlılık ve zaman uyumsuz işlemler |
| zaman uyumsuz işlemi | async Task<T> ... |
IAsyncOperation<T> ... |
IAsyncOperation arabirimi, C++/WinRT ile Eşzamanlılık ve zaman uyumsuz işlemler |
| Fire-and-forget yöntemi (zaman uyumsuz olduğunu ima eder) | async void ... |
winrt::fire_and_forget ... |
CopyButton_Click yönteminitaşıma, çalıştır ve unut |
| Numaralandırılmış sabite erişme | E.Value |
E::Value |
DisplayChangedFormats yöntemini taşıma |
| İşbirliğiyle bekleme | await ... |
co_await ... |
CopyButton_Click metodunu taşıma |
| Özel alan olarak öngörülen türlerin koleksiyonu | private List<MyRuntimeClass> myRuntimeClasses = new List<MyRuntimeClass>(); |
std::vector<MyNamespace::MyRuntimeClass>m_myRuntimeClasses; |
|
| GUID oluşturma | private static readonly Guid myGuid = new Guid("C380465D-2271-428C-9B83-ECEA3B4A85C1"); |
winrt::guid myGuid{ 0xC380465D, 0x2271, 0x428C, { 0x9B, 0x83, 0xEC, 0xEA, 0x3B, 0x4A, 0x85, 0xC1} }; |
|
| Ad alanı ayırıcısı | A.B.T |
A::B::T |
|
| Sıfır | null |
nullptr |
UpdateStatus yöntemini port etme |
| Bir tür nesnesi elde etme | typeof(MyType) |
winrt::xaml_typename<MyType>() |
Senaryoları özellik taşıma |
| Bir yöntem için parametre bildirimi | MyType |
MyType const& |
parametre geçirme |
| Asenkron yöntem için parametre bildirimi | MyType |
MyType |
parametre geçirme |
| Statik yöntem çağırma | T.Method() |
T::Method() |
|
| Dize |
stringveya System.String |
winrt::hstring | C++/WinRT'de Dize İşleme |
| Dize değişmez değeri | "a string literal" |
L"a string literal" |
Oluşturucuyu taşıma, Geçerlive FEATURE_NAME |
| Çıkarılmış (veya türetilmiş) tür | var |
auto |
BuildClipboardFormatsOutputString yönteminin taşınması |
| Kullanım yönergesi | using A.B.C; |
using namespace A::B::C; |
Oluşturucuyu taşıma, Geçerlive FEATURE_NAME |
| Düz metin/ham dize değişmez değeri | @"verbatim string literal" |
LR"(raw string literal)" |
DisplayToast yöntemini aktarma |
Uyarı
Belirli bir ad alanı için bir başlık dosyası using namespace yönergesi içermiyorsa, bu ad alanına ait tüm tür adlarını tam olarak belirtmeniz gerekir; veya en azından derleyicinin bunları bulabilmesi için yeterince belirtmelisiniz. Örnek için bkz.
Sınıfları ve üyeleri taşıma
Her C# türü için bunu bir Windows Çalışma Zamanı türüne mi yoksa normal bir C++ sınıfına/yapısına/numaralandırmasına mı taşımanız gerektiğine karar vermeniz gerekir. Daha fazla bilgi edinmek ve bu kararların nasıl alınıp alınağını gösteren ayrıntılı örnekler için bkz. C#Pano örneğini C++/WinRT'ye taşıma.
C# özelliği genellikle bir erişimci işlevi, bir mutator işlevi ve bir yedekleme veri üyesi olur. Daha fazla bilgi ve örnek için bkz. IsClipboardContentChangedEnabled özelliğinitaşıma.
Statik olmayan alanlar için, bunları
C# statik alanı bir C++/WinRT statik erişimci ve/veya mutator işlevine dönüşür. Daha fazla bilgi ve örnek için bkz. Kurucu fonksiyonun taşınması, Geçerlive FEATURE_NAME.
Üye işlevleri için de her biri için IDL'ye ait olup olmadığına veya uygulama türünüzün genel veya özel üye işlevi olup olmadığına karar vermeniz gerekir. Daha fazla bilgi ve karar verme örnekleri için bkz. IDL ve MainPage türü.
XAML işaretlemesini ve varlık dosyalarını aktarma
Pano örneğini C#'den C++/WinRT'ye taşıma
Dil ile ilgili işlemleri içeren değişiklikler
| Kategori | C# (programlama dili) | C++/WinRT | Ayrıca bakınız |
|---|---|---|---|
| Asenkron bir yöntemde yaşam süresi yönetimi | Mevcut Değil |
auto lifetime{ get_strong() }; veyaauto lifetime = get_strong(); |
CopyButton_Click metodunu taşıma |
| Atık Bertarafı | using (var t = v) |
auto t{ v };t.Close(); // or let wrapper destructor do the work |
CopyImage yöntemini taşıma |
| Nesne oluşturma | new MyType(args) |
MyType{ args } veyaMyType(args) |
Senaryoları özellik taşıma |
| Başlatılmamış referans oluşturma | MyType myObject; |
MyType myObject{ nullptr }; veyaMyType myObject = nullptr; |
Oluşturucuyu taşıma, Geçerlive FEATURE_NAME |
| Args ile değişkene nesne oluşturma | var myObject = new MyType(args); |
auto myObject{ MyType{ args } }; veya auto myObject{ MyType(args) }; veya auto myObject = MyType{ args }; veya auto myObject = MyType(args); veya MyType myObject{ args }; veya MyType myObject(args); |
Footer_Click yöntemini taşıma |
| Nesneyi args olmadan değişkene oluşturma | var myObject = new T(); |
MyType myObject; |
BuildClipboardFormatsOutputString yönteminin taşınması |
| Nesne başlatma kısayolu | var p = new FileOpenPicker{ViewMode = PickerViewMode.List}; |
FileOpenPicker p;p.ViewMode(PickerViewMode::List); |
|
| Toplu vektör işlemi | var p = new FileOpenPicker{FileTypeFilter = { ".png", ".jpg", ".gif" }}; |
FileOpenPicker p;p.FileTypeFilter().ReplaceAll({ L".png", L".jpg", L".gif" }); |
CopyButton_Click metodunu taşıma |
| Koleksiyon üzerinde yinele | foreach (var v in c) |
for (auto&& v : c) |
BuildClipboardFormatsOutputString yönteminin taşınması |
| Özel durumu yakala | catch (Exception ex) |
catch (winrt::hresult_error const& ex) |
PasteButton_Click yöntemini taşıma |
| Özel durum ayrıntıları | ex.Message |
ex.message() |
PasteButton_Click yöntemini taşıma |
| Özellik değerini al | myObject.MyProperty |
myObject.MyProperty() |
NotifyUser yöntemini taşımak |
| Özellik değeri ayarlama | myObject.MyProperty = value; |
myObject.MyProperty(value); |
|
| Özellik değerini artırma | myObject.MyProperty += v; |
myObject.MyProperty(thing.Property() + v);Dizeler için oluşturucuya geçin |
|
| ToString() | myObject.ToString() |
winrt::to_hstring(myObject) |
ToString() |
| Dil dizesini Windows Çalışma Zamanı dizesine | Mevcut Değil | winrt::hstring{ s } |
|
| Dize oluşturma | StringBuilder builder;builder.Append(...); |
std::wostringstream builder;builder << ...; |
Dize oluşturma |
| Dize enterpolasyonu | $"{i++}) {s.Title}" |
winrt::to_hstring, ve/veya winrt::hstring::operator+ | OnNavigatedTo yöntemini taşıma |
| Karşılaştırma için boş dize | System.String.Empty | winrt::hstring::empty | UpdateStatus yöntemini port etme |
| Boş dize oluşturma | var myEmptyString = String.Empty; |
winrt::hstring myEmptyString{ L"" }; |
|
| Sözlük işlemleri | map[k] = v; // replaces any existingv = map[k]; // throws if not presentmap.ContainsKey(k) |
map.Insert(k, v); // replaces any existingv = map.Lookup(k); // throws if not presentmap.HasKey(k) |
|
| Tür dönüştürme (başarısızlıkta hata fırlatma) | (MyType)v |
v.as<MyType>() |
Footer_Click yöntemini taşıma |
| Tür dönüştürme (hatada null) | v as MyType |
v.try_as<MyType>() |
PasteButton_Click yöntemini taşıma |
| x:Name içeren XAML öğeleri özelliklerdir | MyNamedElement |
MyNamedElement() |
Oluşturucuyu taşıma, Geçerlive FEATURE_NAME |
| Kullanıcı arabirimi iş parçacığına geçiş yap | CoreDispatcher.RunAsync | CoreDispatcher.RunAsyncveya winrt::resume_foreground | NotifyUser yönteminiuyarlama ve HistoryAndRoaming yöntemini |
| XAML sayfasındaki kesinlik temelli kodda UI öğesi oluşturma | Bkz. kullanıcı arabirimi öğesi oluşturma | Bkz. kullanıcı arabirimi öğesi oluşturma |
Aşağıdaki bölümlerde tablodaki bazı öğelerle ilgili daha ayrıntılı bilgi ve bulabilirsiniz.
UI öğesi oluşturma
Bu kod örnekleri, XAML sayfasının kesinlik temelli kodunda ui öğesinin oluşturulmasını gösterir.
var myTextBlock = new TextBlock()
{
Text = "Text",
Style = (Windows.UI.Xaml.Style)this.Resources["MyTextBlockStyle"]
};
TextBlock myTextBlock;
myTextBlock.Text(L"Text");
myTextBlock.Style(
winrt::unbox_value<Windows::UI::Xaml::Style>(
Resources().Lookup(
winrt::box_value(L"MyTextBlockStyle")
)
)
);
ToString()
C# türleri Object.ToString yöntemini sağlar.
int i = 2;
var s = i.ToString(); // s is a System.String with value "2".
C++/WinRT bu tesisi doğrudan sağlamaz, ancak alternatiflere dönebilirsiniz.
int i{ 2 };
auto s{ std::to_wstring(i) }; // s is a std::wstring with value L"2".
C++/WinRT, sınırlı sayıda tür için winrt::to_hstring’yi de destekler. Dizeleştirmek istediğiniz ek türler için aşırı yüklemeler eklemeniz gerekir.
| Dil | int'i string'e dönüştür | Enum'u dizgeye dönüştür |
|---|---|---|
| C# (programlama dili) | string result = "hello, " + intValue.ToString();string result = $"hello, {intValue}"; |
string result = "status: " + status.ToString();string result = $"status: {status}"; |
| C++/WinRT | hstring result = L"hello, " + to_hstring(intValue); |
// must define overload (see below)hstring result = L"status: " + to_hstring(status); |
Sabit listeyi bir dizeye dönüştürme durumunda, winrt::to_hstringuygulamasını sağlamanız gerekir.
namespace winrt
{
hstring to_hstring(StatusEnum status)
{
switch (status)
{
case StatusEnum::Success: return L"Success";
case StatusEnum::AccessDenied: return L"AccessDenied";
case StatusEnum::DisabledByPolicy: return L"DisabledByPolicy";
default: return to_hstring(static_cast<int>(status));
}
}
}
Bu dizeleştirmeler genellikle veri bağlama işlemi tarafından dolaylı olarak kullanılır.
<TextBlock>
You have <Run Text="{Binding FlowerCount}"/> flowers.
</TextBlock>
<TextBlock>
Most recent status is <Run Text="{x:Bind LatestOperation.Status}"/>.
</TextBlock>
Bu bağlamalar, bağlı özelliğin winrt::to_hstring dönüştürme işlemini gerçekleştirir. İkinci örnekte (StatusEnum) kendi winrt::to_hstringaşırı yüklemesini sağlamanız gerekir, aksi takdirde derleyici hatası alırsınız.
Ayrıca bkz. Footer_Click yönteminitaşıma.
Dize oluşturma
Dize derleme için C# yerleşik bir StringBuilder türüne sahiptir.
| Kategori | C# (programlama dili) | C++/WinRT |
|---|---|---|
| Dize oluşturma | StringBuilder builder;builder.Append(...); |
std::wostringstream builder;builder << ...; |
| Null değerleri koruyarak Windows Çalışma Zamanı dizesi ekleyin | builder.Append(s); |
builder << std::wstring_view{ s }; |
| Yeni satır ekleme | builder.Append(Environment.NewLine); |
builder << std::endl; |
| Sonuda erişme | s = builder.ToString(); |
ws = builder.str(); |
Ayrıca bkz. BuildClipboardFormatsOutputString yönteminitaşıma ve DisplayChangedFormats yönteminitaşıma.
Ana kullanıcı arabirimi iş parçacığında kod çalıştırma
Bu örnek, Barkod tarayıcı örneğindenalınmıştır.
C# projesindeki ana kullanıcı arabirimi iş parçacığı üzerinde çalışmak istediğinizde, genellikle aşağıdaki gibi CoreDispatcher.RunAsync yöntemini kullanırsınız.
private async void Watcher_Added(DeviceWatcher sender, DeviceInformation args)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// Do work on the main UI thread here.
});
}
Bunu C++/WinRT ile ifade etmek çok daha kolaydır. İlk askıya alma noktasından (bu örnekte co_await) sonra bunlara erişmek istediğimiz varsayımı üzerine parametreleri değere göre kabul ettiğimize dikkat edin. Daha fazla bilgi için bkz. parametre geçirme
winrt::fire_and_forget Watcher_Added(DeviceWatcher sender, winrt::DeviceInformation args)
{
co_await Dispatcher();
// Do work on the main UI thread here.
}
İşi varsayılan dışındaki bir öncelik seviyesinde yapmanız gerekiyorsa, farklı öncelik seviyeleri kabul eden aşırı yükleme işlevi olan winrt::resume_foreground işlevine bakın. winrt::resume_foregroundçağrısını beklemenin nasıl olduğunu gösteren kod örnekleri için bkz. iş parçacığı bağımlılığını göz önünde bulundurarak programlama.
C++/WinRT'ye özgü taşıma görevleri
IDL'de çalışma zamanı sınıflarınızı tanımlama
İhtiyacınız olan C++/WinRT Windows ad alanı üst bilgi dosyalarını ekleyin
C++/WinRT'de, bir Windows ad alanından tür kullanmak istediğinizde, karşılık gelen C++/WinRT Windows ad alanı üst bilgi dosyasını eklemeniz gerekir. Örnek için bkz. NotifyUser yönteminitaşıma.
Kutulama ve kutu açma
C# skalerleri otomatik olarak nesneler halinde kutular. C++/WinRT, winrt::box_value işlevini açıkça çağırmanızı gerektirir. Her iki dil de açıkça kutunun açılmasını gerektirir. Bkz. C++/WinRT ile Kutuya Alma ve Kutudan Çıkartma.
Aşağıdaki tablolarda bu tanımları kullanacağız.
| C# (programlama dili) | C++/WinRT |
|---|---|
int i; |
int i; |
string s; |
winrt::hstring s; |
object o; |
IInspectable o; |
| Operasyon | C# (programlama dili) | C++/WinRT |
|---|---|---|
| Boks | o = 1;o = "string"; |
o = box_value(1);o = box_value(L"string"); |
| Kutudan çıkarma | i = (int)o;s = (string)o; |
i = unbox_value<int>(o);s = unbox_value<winrt::hstring>(o); |
C++/CX ve C# bir değer türüne null işaretçisini kaldırmaya çalışırsanız özel durumlar oluşturur. C++/WinRT bunu bir programlama hatası olarak kabul eder ve çöker. C++/WinRT'de, nesnenin sandığınız türde olmadığı durumu işlemek istiyorsanız winrt::unbox_value_or işlevini kullanın.
| Senaryo | C# (programlama dili) | C++/WinRT |
|---|---|---|
| Bilinen bir tamsayıyı açma | i = (int)o; |
i = unbox_value<int>(o); |
| o null ise | System.NullReferenceException |
Çökme |
| o kutulu bir int değilse | System.InvalidCastException |
Çökme |
| int'i ayıklayın, null ise geri dönüş değerini kullanın; başka bir şey olursa hata verin | i = o != null ? (int)o : fallback; |
i = o ? unbox_value<int>(o) : fallback; |
| Mümkünse int'i kutusundan çıkar; diğer durumlar için yedek bir seçenek kullan. | i = as int? ?? fallback; |
i = unbox_value_or<int>(o, fallback); |
Örnek için bkz. OnNavigatedTo yönteminitaşıma ve Footer_Click yönteminitaşıma.
Diziyi kutulama ve kutudan çıkarma
Dize, bazı yönlerden bir değer türü ve diğer şekillerde bir başvuru türüdür. C# ve C++/WinRT dizeleri farklı şekilde ele alır.
ABI türü HSTRING, referans sayımlı bir dizeye yönelik bir işaretçidir. Ancak IInspectabletüretilmediğinden, bu nedenle teknik olarak bir nesne değildir. Ayrıca, boş bir HSTRING boş dizeyi temsil eder. IInspectable türetilmeyen öğelerin kutulanması, IReference<T>içine sarmalanarak yapılır ve Windows Çalışma Zamanı, PropertyValue nesnesi biçiminde standart bir uygulama sağlar (özel türler PropertyType::OtherTypeolarak bildirilir).
C# bir Windows Çalışma Zamanı dizesini başvuru türü olarak temsil ederken; C++/WinRT bir dizeyi değer türü olarak yansıtır. Bu, kutulanmış null dizenin oraya nasıl girdiğinize bağlı olarak farklı gösterimleri olabileceği anlamına gelir.
| Davranış | C# (programlama dili) | C++/WinRT |
|---|---|---|
| Bildirim | object o;string s; |
IInspectable o;hstring s; |
| Dize türü kategorisi | Referans türü | Değer türü |
| null HSTRING projeleri olarak | "" |
hstring{} |
Null ve "" aynı mı? |
Hayı | Evet |
| Null değerinin geçerliliği | s = null;s.Length NullReferenceException hatasına neden olur |
s = hstring{};s.size() == 0 (geçerli) |
| Nesneye null dize atarsanız | o = (string)null;o == null |
o = box_value(hstring{});o != nullptr |
nesneye "" atarsanız |
o = "";o != null |
o = box_value(hstring{L""});o != nullptr |
Temel kutulama ve kutu açma.
| Operasyon | C# (programlama dili) | C++/WinRT |
|---|---|---|
| Dizeyi kutuya koymak | o = s;Boş dize null olmayan nesneye dönüşür. |
o = box_value(s);Boş dize null olmayan nesneye dönüşür. |
| Bilinen bir dizeyi kutudan çıkarma | s = (string)o;Null nesne null dizeye dönüşür. String değilse InvalidCastException oluşur. |
s = unbox_value<hstring>(o);Null nesne çöküyor. Bir dize değilse çöküyor. |
| Muhtemel bir dizeyi kutusundan çıkar | s = o as string;Null nesne veya dize şeklinde olmayan bir şey, null dizeye dönüşür. VEYA s = o as string ?? fallback;Null ya da olmayan bir dize yedek haline gelir. Boş dize korundu. |
s = unbox_value_or<hstring>(o, fallback);Null ya da olmayan bir dize yedek haline gelir. Boş dize korundu. |
Bir sınıfı {Binding} işaretleme uzantısı için kullanılabilir hale getirme
{Binding} işaretleme uzantısını veri türünüzle veri bağlamak amacıyla kullanmayı düşünüyorsanız {Binding} kullanılarak bildirilen Bağlama nesnesine vebakın.
XAML işaretlemesindeki nesneleri kullanma
C# projesinde, XAML işaretlemesindeki özel üyeleri ve adlandırılmış öğeleri kullanabilirsiniz. Ancak C++/WinRT'de XAML {x:Bind} işaretleme uzantısı kullanılarak kullanılan tüm varlıklar IDL'de genel kullanıma sunulmalıdır.
Ayrıca, Boole türüne bağlanma C# dilinde true veya false olarak görüntülenir, ancak C++/WinRT'de Windows.Foundation.IReference`1<Boole> olarak gösterilir.
Daha fazla bilgi ve kod örnekleri için bakınız: İşaretlemeden nesneleri tüketme.
Veri kaynağını XAML işaretlemesi için kullanılabilir hale getirme
C++/WinRT sürüm 2.0.190530.8 veya sonraki bir sürümde, winrt::single_threaded_observable_vector hem IObservableVector<T>hem de IObservableVector<IInspectable>destekleyen gözlemlenebilir bir vektör oluşturur. Örnek için bkz. Senaryoları özelliğinitaşıma.
Midl dosyanızı (.idl) bunun gibi yazabilirsiniz (ayrıca bkz. Factoring çalışma zamanı sınıflarını Midl dosyalarına (.idl)).
namespace Bookstore
{
runtimeclass BookSku { ... }
runtimeclass BookstoreViewModel
{
Windows.Foundation.Collections.IObservableVector<BookSku> BookSkus{ get; };
}
runtimeclass MainPage : Windows.UI.Xaml.Controls.Page
{
MainPage();
BookstoreViewModel MainViewModel{ get; };
}
}
Ve bu şekilde uygulayın.
// BookstoreViewModel.h
...
struct BookstoreViewModel : BookstoreViewModelT<BookstoreViewModel>
{
BookstoreViewModel()
{
m_bookSkus = winrt::single_threaded_observable_vector<Bookstore::BookSku>();
m_bookSkus.Append(winrt::make<Bookstore::implementation::BookSku>(L"To Kill A Mockingbird"));
}
Windows::Foundation::Collections::IObservableVector<Bookstore::BookSku> BookSkus();
{
return m_bookSkus;
}
private:
Windows::Foundation::Collections::IObservableVector<Bookstore::BookSku> m_bookSkus;
};
...
Daha fazla bilgi için bkz. XAML öğeleri denetimleri; bir C++/WinRT koleksiyonuna bağlamave C++/WinRT ile Koleksiyonlar.
Bir veri kaynağını XAML işaretlemesi için kullanılabilir hale getirme (C++/WinRT 2.0.190530.8'den önce)
XAML veri bağlama, bir öğe kaynağının IIterable<IInspectable>uygulamasını gerçekleştirmesini ve bunun yanında aşağıdaki arabirim birleşimlerinden birini kullanmasını gerektirir.
- IObservableVector<IInspectable>
- IBindableVector ve INotifyCollectionChanged
- IBindableVector ve IBindableObservableVector
- IBindableVector tek başına (değişikliklere yanıt vermez)
- IVector<IInspectable>
- IBindableIterable (öğeleri yineler ve özel koleksiyona kaydeder)
IVector<T> gibi genel bir arabirim çalışma zamanında algılanamaz. Her IVector<T>, Tişlevi olan farklı bir arabirim tanımlayıcısı (IID) vardır. Herhangi bir geliştirici T kümesini rastgele genişletebilir, bu nedenle açıkça XAML bağlama kodu sorgulanacağı tam kümeyi asla bilemez. IEnumerable<T> uygulayan her CLR nesnesi otomatik olarak IEnumerableuyguladığından bu kısıtlama C# için sorun değildir. ABI düzeyinde bu, IObservableVector<T> uygulayan her nesnenin, otomatik olarak IObservableVector<IInspectable>'ı uyguladığı anlamına gelir.
C++/WinRT bu garantiyi sunmaz. C++/WinRT çalışma zamanı sınıfı IObservableVector<T>uygularsa, bir şekilde IObservableVector<IInspectable> uygulamasının da sağlandığını varsayamayız.
Sonuç olarak, önceki örneğin nasıl görünmesi gerektiği aşağıda verilmiştir.
...
runtimeclass BookstoreViewModel
{
// This is really an observable vector of BookSku.
Windows.Foundation.Collections.IObservableVector<Object> BookSkus{ get; };
}
Ve uygulama.
// BookstoreViewModel.h
...
struct BookstoreViewModel : BookstoreViewModelT<BookstoreViewModel>
{
BookstoreViewModel()
{
m_bookSkus = winrt::single_threaded_observable_vector<Windows::Foundation::IInspectable>();
m_bookSkus.Append(winrt::make<Bookstore::implementation::BookSku>(L"To Kill A Mockingbird"));
}
// This is really an observable vector of BookSku.
Windows::Foundation::Collections::IObservableVector<Windows::Foundation::IInspectable> BookSkus();
{
return m_bookSkus;
}
private:
Windows::Foundation::Collections::IObservableVector<Windows::Foundation::IInspectable> m_bookSkus;
};
...
m_bookSkusiçindeki nesnelere erişmeniz gerekiyorsa, bunları Bookstore::BookSku'a geri göndermeniz gerekir.
Widget MyPage::BookstoreViewModel(winrt::hstring title)
{
for (auto&& obj : m_bookSkus)
{
auto bookSku = obj.as<Bookstore::BookSku>();
if (bookSku.Title() == title) return bookSku;
}
return nullptr;
}
Türetilmiş sınıflar
Bir çalışma zamanı sınıfından türetmek için temel sınıfın birleştirilebilirolması gerekir. C# sınıflarınızı birleştirilebilir hale getirmek için herhangi bir özel adım atmanızı gerektirmez, ancak C++/WinRT yapar. Sınıfınızın temel sınıf olarak kullanılabilir olmasını istediğinizi belirtmek için korumasız anahtar sözcüğü kullanırsınız.
unsealed runtimeclass BasePage : Windows.UI.Xaml.Controls.Page
{
...
}
runtimeclass DerivedPage : BasePage
{
...
}
uygulama türünüzün üst bilgi dosyasındatüretilmiş sınıfın otomatik olarak oluşturulan üst bilgisini eklemeden önce temel sınıf üst bilgi dosyasını eklemeniz gerekir. Aksi takdirde "Bu türün ifade olarak geçersiz kullanımı" gibi hatalar alırsınız.
// DerivedPage.h
#include "BasePage.h" // This comes first.
#include "DerivedPage.g.h" // Otherwise this header file will produce an error.
namespace winrt::MyNamespace::implementation
{
struct DerivedPage : DerivedPageT<DerivedPage>
{
...
}
}
Önemli API'ler
- winrt ad alanı