Aracılığıyla paylaş


C'den C++/WinRT'ye gitme#

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 bölümüne atlayabilirsiniz.

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 yardımcı konusuna bakın. Bu rehberi takip ederek ve adımları izlerken, örneği kendi başınıza taşıyıp taşıma pratiği yapabilir ve deneyim kazanabilirsiniz.

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 .idl dosyası 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 ve bir Windows Çalışma Zamanı bileşeninde çalışma zamanı sınıfı yazıyorsanız.
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 olması iyi bir fikirdir (bkz. Bu işaretçisine bir sınıf üyesi eş yordam) güvenle erişme).

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 Yazar API'lerinin başlangıcına bakın. Ardından aşağıdaki sonraki üç satıra bakın.
Ç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 klasöründe oluşturulan saplama dosyalarını ( ve ) yeniden derleyin ve bakın (Proje düğümü seçiliÇözüm Gezgini'nde Tüm Dosyaları Göster seçeneğinin açık olduğundan emin olun). Saplama dosyalarını projenizde bulunan dosyalarla karşılaştırın, dosyaları ekleyin veya işlev imzalarını gerektiği şekilde ekleyin/güncelleştirin. Saplama dosyası söz dizimi her zaman doğrudur, bu nedenle derleme hatalarını en aza indirmek için kullanmanızı öneririz. Projenizdeki yer tutucular, yer tutucu dosyalarındakilerle eşleştiğinde, C# kodunu aktararak bunları uygulayabilirsiniz.
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)o
C++/WinRT: unbox_value<Value>(o)
Kutu açma başarısız olursa atar. Ayrıca bkz. Boxing ve unboxing.

C#: o as Value? ?? fallback
C++/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)o
C++/WinRT: o.as<Class>()
Dönüştürme başarısız olursa atar.

C#: o as Class
C++/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 açıklandığı gibi, olay işleyicisi temsilcisini kaydetmek/iptal etmek için çeşitli söz dizimsel seçenekleriniz vardır. Ayrıca bkz. EnableClipboardContentChangedNotifications yönteminitaşıma.

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, OpenButton_Click yönteminiz,XAML işaretlemesine kaydetmek istiyorsanız, uygulama türündegenel olmalıdır. Bir olay işleyicisini yalnızca kesinlik temelli koda kaydederseniz, olay işleyicisinin genel olması gerekmez.

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 aktardığınız C# projesinin işaretlemeden olay işleyicisine bağladığı senaryodur (bu senaryoda daha fazla arka plan için bkz. x:Bind) İşlevleri ).

<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);

Uyarı

void Fire olarak uygulasanız veunutsanız bile işlevi olarak bildirin.

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. DisplayToast yönteminitaşıma .

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ıuygulama türünüzün veri üyesi yapın.

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 durumunda, C# ve C++/WinRT projesinde aynı XAML işaretlemesini (kaynaklar dahil) ve varlık dosyalarını kullanabildik. Bazı durumlarda, bunu başarmak için işaretleme düzenlemeleri yapılması gerekir. Bkz. MainPagetaşıma işlemini tamamlamak için gereken XAML'yi ve stilleri kopyalama.

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() }; veya
auto 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 } veya
MyType(args)
Senaryoları özellik taşıma
Başlatılmamış referans oluşturma MyType myObject; MyType myObject{ nullptr }; veya
MyType 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 existing
v = map[k]; // throws if not present
map.ContainsKey(k)
map.Insert(k, v); // replaces any existing
v = map.Lookup(k); // throws if not present
map.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.

IDL'de çalışma zamanı sınıflarınızı tanımlama

MainPage türü için IDL bölümüne bakın ve dosyalarınızıbirleştirin.

İ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ı