Aracılığıyla paylaş


Veri bağlamaya genel bakış

Bu konu başlığında, bir denetimin (veya başka bir kullanıcı arabirimi öğesinin) tek bir öğeye nasıl bağlanacağınız veya bir öğe denetiminin Evrensel Windows Platformu (UWP) uygulamasındaki bir öğe koleksiyonuna nasıl bağlanacağınız gösterilir. Buna ek olarak, öğelerin işlenmesini denetlemeyi, bir seçimi temel alan ayrıntılar görünümünü uygulamayı ve verileri görüntüleme için dönüştürmeyi gösteririz. Daha ayrıntılı bilgi için bkz. Derinlemesine veri bağlama.

Önkoşullar

Bu konu başlığında, temel bir UWP uygulamasının nasıl oluşturulacağını bildiğiniz varsayılır. İlk UWP uygulamanızı oluşturma yönergeleri için bkz. Windows uygulamalarını kullanmaya başlama.

Projeyi oluşturma

Yeni bir Blank Application (Windows Universal) projesi oluşturun. Buna "Hızlı Başlangıç" adını verin.

Tek bir öğeye bağlama

Her bağlama bir bağlama hedef ve bir bağlama kaynağından oluşur. Genellikle, hedef bir denetimin veya başka bir ui öğesinin özelliğidir ve kaynak bir sınıf örneğinin (veri modeli veya görünüm modeli) özelliğidir. Bu örnekte bir denetimin tek bir öğeye nasıl bağlanacağınız gösterilmektedir. Hedef, TextBlock'ün Text özelliğidir. Kaynak, ses kaydını temsil eden Kayıt adlı basit bir sınıfın örneğidir. Önce sınıfa bakalım.

C# veya C++/CX kullanıyorsanız projenize yeni bir sınıf ekleyin ve sınıfı Kayıt olarak adlandırın.

C++/WinRT kullanıyorsanız, aşağıdaki C++/WinRT kod örneği listesinde gösterildiği gibi adlı yeni Midl Dosyası (.idl) öğelerini projeye ekleyin. Bu yeni dosyaların içeriğini listede gösterilen MIDL 3.0 koduyla değiştirin, ardından Recording.h, .cpp, RecordingViewModel.h ve .cpp oluşturmak için projeyi derleyin ve sonra oluşturulan dosyalara, listeyle eşleşecek şekilde kod ekleyin. Oluşturulan dosyalar ve bunları projenize nasıl kopyalayacağınız hakkında daha fazla bilgi için XAML denetimlerine;bir C++/WinRT özelliğine bağlama konusuna bakın.

namespace Quickstart
{
    public class Recording
    {
        public string ArtistName { get; set; }
        public string CompositionName { get; set; }
        public DateTime ReleaseDateTime { get; set; }
        public Recording()
        {
            this.ArtistName = "Wolfgang Amadeus Mozart";
            this.CompositionName = "Andante in C for Piano";
            this.ReleaseDateTime = new DateTime(1761, 1, 1);
        }
        public string OneLineSummary
        {
            get
            {
                return $"{this.CompositionName} by {this.ArtistName}, released: "
                    + this.ReleaseDateTime.ToString("d");
            }
        }
    }
    public class RecordingViewModel
    {
        private Recording defaultRecording = new Recording();
        public Recording DefaultRecording { get { return this.defaultRecording; } }
    }
}
// Recording.idl
namespace Quickstart
{
    runtimeclass Recording
    {
        Recording(String artistName, String compositionName, Windows.Globalization.Calendar releaseDateTime);
        String ArtistName{ get; };
        String CompositionName{ get; };
        Windows.Globalization.Calendar ReleaseDateTime{ get; };
        String OneLineSummary{ get; };
    }
}

// RecordingViewModel.idl
import "Recording.idl";

namespace Quickstart
{
    runtimeclass RecordingViewModel
    {
        RecordingViewModel();
        Quickstart.Recording DefaultRecording{ get; };
    }
}

// Recording.h
// Add these fields:
...
#include <sstream>
...
private:
    std::wstring m_artistName;
    std::wstring m_compositionName;
    Windows::Globalization::Calendar m_releaseDateTime;
...

// Recording.cpp
// Implement like this:
...
Recording::Recording(hstring const& artistName, hstring const& compositionName, Windows::Globalization::Calendar const& releaseDateTime) :
    m_artistName{ artistName.c_str() },
    m_compositionName{ compositionName.c_str() },
    m_releaseDateTime{ releaseDateTime } {}

hstring Recording::ArtistName(){ return hstring{ m_artistName }; }
hstring Recording::CompositionName(){ return hstring{ m_compositionName }; }
Windows::Globalization::Calendar Recording::ReleaseDateTime(){ return m_releaseDateTime; }

hstring Recording::OneLineSummary()
{
    std::wstringstream wstringstream;
    wstringstream << m_compositionName.c_str();
    wstringstream << L" by " << m_artistName.c_str();
    wstringstream << L", released: " << m_releaseDateTime.MonthAsNumericString().c_str();
    wstringstream << L"/" << m_releaseDateTime.DayAsString().c_str();
    wstringstream << L"/" << m_releaseDateTime.YearAsString().c_str();
    return hstring{ wstringstream.str().c_str() };
}
...

// RecordingViewModel.h
// Add this field:
...
#include "Recording.h"
...
private:
    Quickstart::Recording m_defaultRecording{ nullptr };
...

// RecordingViewModel.cpp
// Implement like this:
...
Quickstart::Recording RecordingViewModel::DefaultRecording()
{
    Windows::Globalization::Calendar releaseDateTime;
    releaseDateTime.Year(1761);
    releaseDateTime.Month(1);
    releaseDateTime.Day(1);
    m_defaultRecording = winrt::make<Recording>(L"Wolfgang Amadeus Mozart", L"Andante in C for Piano", releaseDateTime);
    return m_defaultRecording;
}
...
// Recording.h
#include <sstream>
namespace Quickstart
{
    public ref class Recording sealed
    {
    private:
        Platform::String^ artistName;
        Platform::String^ compositionName;
        Windows::Globalization::Calendar^ releaseDateTime;
    public:
        Recording(Platform::String^ artistName, Platform::String^ compositionName,
            Windows::Globalization::Calendar^ releaseDateTime) :
            artistName{ artistName },
            compositionName{ compositionName },
            releaseDateTime{ releaseDateTime } {}
        property Platform::String^ ArtistName
        {
            Platform::String^ get() { return this->artistName; }
        }
        property Platform::String^ CompositionName
        {
            Platform::String^ get() { return this->compositionName; }
        }
        property Windows::Globalization::Calendar^ ReleaseDateTime
        {
            Windows::Globalization::Calendar^ get() { return this->releaseDateTime; }
        }
        property Platform::String^ OneLineSummary
        {
            Platform::String^ get()
            {
                std::wstringstream wstringstream;
                wstringstream << this->CompositionName->Data();
                wstringstream << L" by " << this->ArtistName->Data();
                wstringstream << L", released: " << this->ReleaseDateTime->MonthAsNumericString()->Data();
                wstringstream << L"/" << this->ReleaseDateTime->DayAsString()->Data();
                wstringstream << L"/" << this->ReleaseDateTime->YearAsString()->Data();
                return ref new Platform::String(wstringstream.str().c_str());
            }
        }
    };
    public ref class RecordingViewModel sealed
    {
    private:
        Recording ^ defaultRecording;
    public:
        RecordingViewModel()
        {
            Windows::Globalization::Calendar^ releaseDateTime = ref new Windows::Globalization::Calendar();
            releaseDateTime->Year = 1761;
            releaseDateTime->Month = 1;
            releaseDateTime->Day = 1;
            this->defaultRecording = ref new Recording{ L"Wolfgang Amadeus Mozart", L"Andante in C for Piano", releaseDateTime };
        }
        property Recording^ DefaultRecording
        {
            Recording^ get() { return this->defaultRecording; };
        }
    };
}

// Recording.cpp
#include "pch.h"
#include "Recording.h"

Ardından, işaretleme sayfanızı temsil eden sınıftan bağlama kaynak sınıfını kullanıma sunun. Bunu, MainPage'eRecordingViewModel türünde bir özellik ekleyerek yaparız.

C++/WinRT kullanıyorsanız, önce MainPage.idl öğesini güncelleştirin. MainPage.h ve .cpp'i yeniden oluşturmak için projeyi derleyin ve bu oluşturulan dosyalardaki değişiklikleri projenizdeki dosyalara birleştirin.

namespace Quickstart
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.ViewModel = new RecordingViewModel();
        }
        public RecordingViewModel ViewModel{ get; set; }
    }
}
// MainPage.idl
// Add this property:
import "RecordingViewModel.idl";
...
RecordingViewModel ViewModel{ get; };
...

// MainPage.h
// Add this property and this field:
...
#include "RecordingViewModel.h"
...
    Quickstart::RecordingViewModel ViewModel();

private:
    Quickstart::RecordingViewModel m_viewModel{ nullptr };
...

// MainPage.cpp
// Implement like this:
...
MainPage::MainPage()
{
    InitializeComponent();
    m_viewModel = winrt::make<RecordingViewModel>();
}
Quickstart::RecordingViewModel MainPage::ViewModel()
{
    return m_viewModel;
}
...
// MainPage.h
...
#include "Recording.h"

namespace Quickstart
{
    public ref class MainPage sealed
    {
    private:
        RecordingViewModel ^ viewModel;
    public:
        MainPage();

        property RecordingViewModel^ ViewModel
        {
            RecordingViewModel^ get() { return this->viewModel; };
        }
    };
}

// MainPage.cpp
...
MainPage::MainPage()
{
    InitializeComponent();
    this->viewModel = ref new RecordingViewModel();
}

Son parça, bir TextBlock'i ViewModel.DefaultRecording.OneLineSummary özelliğine bağlamaktır.

<Page x:Class="Quickstart.MainPage" ... >
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="{x:Bind ViewModel.DefaultRecording.OneLineSummary}"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"/>
    </Grid>
</Page>

C++/WinRTkullanıyorsanız, projenin derlenmesi için MainPage::ClickHandler işlevini kaldırmanız gerekir.

Sonuç şu şekildedir.

Metin bloğu bağlama

Bir koleksiyonun öğelerine bağlanma

Yaygın bir senaryo, bir iş nesneleri koleksiyonuna bağlanmaktır. C# ve Visual Basic'te genel ObservableCollection<T> sınıfı, INotifyPropertyChanged ve INotifyCollectionChanged arabirimlerini uyguladığından veri bağlama için iyi bir koleksiyon seçimidir. Bu arabirimler, öğeler eklendiğinde veya kaldırıldığında ya da listenin bir özelliği değiştiğinde bağlamalara değişiklik bildirimi sağlar. İlişkili denetimlerinizin koleksiyondaki nesnelerin özelliklerindeki değişikliklerle güncelleştirilmesini istiyorsanız, iş nesnesi de INotifyPropertyChanged uygulaması gerekir. Daha fazla bilgi için bkz. Ayrıntılı Veri Bağlama.

C++/WinRT kullanıyorsanız, XAML öğeleri denetimlerinde gözlemlenebilir bir koleksiyona bağlama; C++/WinRT koleksiyonuna bağlama hakkında daha fazla bilgi edinebilirsiniz. Önce bu konuyu okursanız, aşağıda gösterilen C++/WinRT kod listesinin amacı daha net olur.

Bu sonraki örnek, bir ListViewRecording nesneleri koleksiyonuna bağlar. Koleksiyonu görünüm modelimize ekleyerek başlayalım. Bu yeni üyeleri RecordingViewModel sınıfına eklemeniz gerekir.

public class RecordingViewModel
{
    ...
    private ObservableCollection<Recording> recordings = new ObservableCollection<Recording>();
    public ObservableCollection<Recording> Recordings{ get{ return this.recordings; } }
    public RecordingViewModel()
    {
        this.recordings.Add(new Recording(){ ArtistName = "Johann Sebastian Bach",
            CompositionName = "Mass in B minor", ReleaseDateTime = new DateTime(1748, 7, 8) });
        this.recordings.Add(new Recording(){ ArtistName = "Ludwig van Beethoven",
            CompositionName = "Third Symphony", ReleaseDateTime = new DateTime(1805, 2, 11) });
        this.recordings.Add(new Recording(){ ArtistName = "George Frideric Handel",
            CompositionName = "Serse", ReleaseDateTime = new DateTime(1737, 12, 3) });
    }
}
// RecordingViewModel.idl
// Add this property:
...
#include <winrt/Windows.Foundation.Collections.h>
...
Windows.Foundation.Collections.IVector<IInspectable> Recordings{ get; };
...

// RecordingViewModel.h
// Change the constructor declaration, and add this property and this field:
...
    RecordingViewModel();
    Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> Recordings();

private:
    Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> m_recordings;
...

// RecordingViewModel.cpp
// Update/add implementations like this:
...
RecordingViewModel::RecordingViewModel()
{
    std::vector<Windows::Foundation::IInspectable> recordings;

    Windows::Globalization::Calendar releaseDateTime;
    releaseDateTime.Month(7); releaseDateTime.Day(8); releaseDateTime.Year(1748);
    recordings.push_back(winrt::make<Recording>(L"Johann Sebastian Bach", L"Mass in B minor", releaseDateTime));

    releaseDateTime = Windows::Globalization::Calendar{};
    releaseDateTime.Month(11); releaseDateTime.Day(2); releaseDateTime.Year(1805);
    recordings.push_back(winrt::make<Recording>(L"Ludwig van Beethoven", L"Third Symphony", releaseDateTime));

    releaseDateTime = Windows::Globalization::Calendar{};
    releaseDateTime.Month(3); releaseDateTime.Day(12); releaseDateTime.Year(1737);
    recordings.push_back(winrt::make<Recording>(L"George Frideric Handel", L"Serse", releaseDateTime));

    m_recordings = winrt::single_threaded_observable_vector<Windows::Foundation::IInspectable>(std::move(recordings));
}

Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> RecordingViewModel::Recordings() { return m_recordings; }
...
// Recording.h
...
public ref class RecordingViewModel sealed
{
private:
    ...
    Windows::Foundation::Collections::IVector<Recording^>^ recordings;
public:
    RecordingViewModel()
    {
        ...
        releaseDateTime = ref new Windows::Globalization::Calendar();
        releaseDateTime->Year = 1748;
        releaseDateTime->Month = 7;
        releaseDateTime->Day = 8;
        Recording^ recording = ref new Recording{ L"Johann Sebastian Bach", L"Mass in B minor", releaseDateTime };
        this->Recordings->Append(recording);
        releaseDateTime = ref new Windows::Globalization::Calendar();
        releaseDateTime->Year = 1805;
        releaseDateTime->Month = 2;
        releaseDateTime->Day = 11;
        recording = ref new Recording{ L"Ludwig van Beethoven", L"Third Symphony", releaseDateTime };
        this->Recordings->Append(recording);
        releaseDateTime = ref new Windows::Globalization::Calendar();
        releaseDateTime->Year = 1737;
        releaseDateTime->Month = 12;
        releaseDateTime->Day = 3;
        recording = ref new Recording{ L"George Frideric Handel", L"Serse", releaseDateTime };
        this->Recordings->Append(recording);
    }
    ...
    property Windows::Foundation::Collections::IVector<Recording^>^ Recordings
    {
        Windows::Foundation::Collections::IVector<Recording^>^ get()
        {
            if (this->recordings == nullptr)
            {
                this->recordings = ref new Platform::Collections::Vector<Recording^>();
            }
            return this->recordings;
        };
    }
};

Ardından Bir ListView'ıViewModel.Recordings özelliğine bağlayın.

<Page x:Class="Quickstart.MainPage" ... >
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ListView ItemsSource="{x:Bind ViewModel.Recordings}"
        HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Page>

Kayıt sınıfı için henüz bir veri şablonu sağlamadık, bu nedenle UI çerçevesinin yapabileceği en iyi şey, ListViewiçindeki her öğe için ToString çağırmaktır. ToString'in varsayılan uygulaması, tür adını döndürmektir.

Liste görünümü bağlama 1

Bunu düzeltmek için , ToString'i geçersiz kılarakOneLineSummary değerini döndürebilir veya bir veri şablonu sağlayabiliriz. Veri şablonu seçeneği daha alışılmış bir çözümdür ve daha esnek bir çözümdür. İçerik denetiminin ContentTemplate özelliğini veya öğe denetiminin ItemTemplate özelliğini kullanarak bir veri şablonu belirtirsiniz. Kayıt için bir veri şablonu tasarlamanın iki yolu ve sonucun çizimi aşağıdadır.

<ListView ItemsSource="{x:Bind ViewModel.Recordings}"
HorizontalAlignment="Center" VerticalAlignment="Center">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local:Recording">
            <TextBlock Text="{x:Bind OneLineSummary}"/>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Liste görünümü bağlama 2

<ListView ItemsSource="{x:Bind ViewModel.Recordings}"
HorizontalAlignment="Center" VerticalAlignment="Center">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local:Recording">
            <StackPanel Orientation="Horizontal" Margin="6">
                <SymbolIcon Symbol="Audio" Margin="0,0,12,0"/>
                <StackPanel>
                    <TextBlock Text="{x:Bind ArtistName}" FontWeight="Bold"/>
                    <TextBlock Text="{x:Bind CompositionName}"/>
                </StackPanel>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Liste görünümü bağlama 3

XAML söz dizimi hakkında daha fazla bilgi için bkz. XAMLile kullanıcı arabirimi oluşturma . Denetim düzeni hakkında daha fazla bilgi için bkz. XAMLile düzenleri tanımlama .

Ayrıntılar görünümü ekleme

ListView öğelerinde Nesneleri kaydetme işleminin tüm ayrıntılarını görüntülemeyi seçebilirsiniz. Ama bu çok yer kaplar. Bunun yerine, öğede bunu tanımlamak için yeterli miktarda veri gösterebilir ve kullanıcı seçim yaptığında, seçili öğenin tüm ayrıntılarını ayrıntılar görünümü olarak bilinen ayrı bir kullanıcı arabiriminde görüntüleyebilirsiniz. Bu düzenleme ana görünüm/ayrıntılar görünümü veya liste/ayrıntılar görünümü olarak da bilinir.

Bunu yapmanın iki yolu vardır. Ayrıntılar görünümünü ListViewSelectedItem özelliğine bağlayabilirsiniz. Veya bir CollectionViewSource kullanabilirsiniz; bu durumda hem ListView hem de ayrıntılar görünümünü CollectionViewSource'a bağlarsınız (bunu yaptığınızda o anda seçili olan öğe sizin için halledilebilir). Her iki teknik de aşağıda gösterilmiştir ve ikisi de aynı sonuçları verir (çizimde gösterilmiştir).

Uyarı

Bu konuyla ilgili olarak şimdiye kadar yalnızca {x:Bind} işaretleme uzantısınıkullandık, ancak aşağıda göstereceğimiz her iki teknik de daha esnek (ancak daha az performanslı) {Binding} işaretleme uzantısınıgerektirir.

C++/WinRT veya Visual C++ bileşen uzantıları (C++/CX) kullanıyorsanız , {Binding} işaretleme uzantısını kullanmak için bindableAttribute özniteliğini bağlamak istediğiniz herhangi bir çalışma zamanı sınıfına eklemeniz gerekir. {x:Bind} kullanmak için bu özniteliğe ihtiyacınız yoktur.

Önemli

C++/WinRT kullanıyorsanız, Windows SDK 10.0.17763.0 (Windows 10, sürüm 1809) veya sonraki bir sürümünü yüklediyseniz BindableAttribute özniteliği kullanılabilir. Bu öznitelik olmadan, {Binding} işaretleme uzantısını kullanabilmek için ICustomPropertyProvider ve ICustomProperty arabirimlerini uygulamanız gerekir.

İlk olarak, işte seçili öğe tekniği.

// No code changes necessary for C#.
// Recording.idl
// Add this attribute:
...
[Windows.UI.Xaml.Data.Bindable]
runtimeclass Recording
...
[Windows::UI::Xaml::Data::Bindable]
public ref class Recording sealed
{
    ...
};

Gerekli olan tek diğer değişiklik işaretlemedir.

<Page x:Class="Quickstart.MainPage" ... >
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <ListView x:Name="recordingsListView" ItemsSource="{x:Bind ViewModel.Recordings}">
                <ListView.ItemTemplate>
                    <DataTemplate x:DataType="local:Recording">
                        <StackPanel Orientation="Horizontal" Margin="6">
                            <SymbolIcon Symbol="Audio" Margin="0,0,12,0"/>
                            <StackPanel>
                                <TextBlock Text="{x:Bind CompositionName}"/>
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <StackPanel DataContext="{Binding SelectedItem, ElementName=recordingsListView}"
            Margin="0,24,0,0">
                <TextBlock Text="{Binding ArtistName}"/>
                <TextBlock Text="{Binding CompositionName}"/>
                <TextBlock Text="{Binding ReleaseDateTime}"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</Page>

CollectionViewSource tekniği için önce sayfa kaynağı olarak bir CollectionViewSource ekleyin.

<Page.Resources>
    <CollectionViewSource x:Name="RecordingsCollection" Source="{x:Bind ViewModel.Recordings}"/>
</Page.Resources>

Ardından, adlandırılmasına gerek kalmayan ListView ve ayrıntılar görünümünde CollectionViewSourcekullanarak bağlamaları ayarlayın. Ayrıntılar görünümünü doğrudan CollectionViewSource'a bağlayarak, yolun koleksiyonun kendisinde bulunamadığı bağlamalarda geçerli öğeye bağlamak istediğinizi ima ettiğinizi unutmayın. Bağlamanın yolu olarak CurrentItem özelliğini belirtmeniz gerekmez, ancak herhangi bir belirsizlik varsa bunu yapabilirsiniz).

...
<ListView ItemsSource="{Binding Source={StaticResource RecordingsCollection}}">
...
<StackPanel DataContext="{Binding Source={StaticResource RecordingsCollection}}" ...>
...

Her durumda aynı sonuç aşağıdadır.

Uyarı

C++ kullanıyorsanız kullanıcı arabiriminiz aşağıdaki çizime tam olarak benzemez: ReleaseDateTime özelliğinin işlenmesi farklıdır. Bu konu hakkında daha fazla bilgi için aşağıdaki bölüme bakın.

Liste görünümü bağlama 4

Görüntüleme için veri değerlerini biçimlendirme veya dönüştürme

Yukarıdaki işlemeyle ilgili bir sorun var. ReleaseDateTime özelliği yalnızca bir tarih değil, bir DateTime'tir (C++ kullanıyorsanız, bir Calendar'tir). Bu nedenle, C# dilinde ihtiyacımız olandan daha hassas bir şekilde görüntüleniyor. C++ dilinde ise bir tür adı olarak işleniyor. Çözümlerden biri, Recording sınıfına this.ReleaseDateTime.ToString("d") eşdeğerini döndüren bir dize özelliği eklemektir. Özelliğe ReleaseDate adını vermek, tarih ve saati değil, yalnızca bir tarihi döndürdüğünü gösterir. ReleaseDateAsString adlandırmak bir dize döndürdüğünü gösterir.

Daha esnek bir çözüm, değer dönüştürücü olarak bilinen bir şeyi kullanmaktır. Aşağıda kendi değer dönüştürücünüzü yazma örneği verilmiştır. C# kullanıyorsanız aşağıdaki kodu kaynak kod dosyanıza Recording.cs ekleyin. C++/WinRT kullanıyorsanız, projeye aşağıdaki C++/WinRT kod örneği listesinde gösterildiği gibi adlı yeni bir Midl Dosyası (.idl) öğesi ekleyin, ve StringFormatter.holuşturmak .cpp için projeyi derleyin, bu dosyaları projenize ekleyin ve sonra kod listelerini bunlara yapıştırın. #include "StringFormatter.h"MainPage.h'e de ekleyin.

public class StringFormatter : Windows.UI.Xaml.Data.IValueConverter
{
    // This converts the value object to the string to display.
    // This will work with most simple types.
    public object Convert(object value, Type targetType,
        object parameter, string language)
    {
        // Retrieve the format string and use it to format the value.
        string formatString = parameter as string;
        if (!string.IsNullOrEmpty(formatString))
        {
            return string.Format(formatString, value);
        }

        // If the format string is null or empty, simply
        // call ToString() on the value.
        return value.ToString();
    }

    // No need to implement converting back on a one-way binding
    public object ConvertBack(object value, Type targetType,
        object parameter, string language)
    {
        throw new NotImplementedException();
    }
}
// pch.h
...
#include <winrt/Windows.Globalization.h>

// StringFormatter.idl
namespace Quickstart
{
    runtimeclass StringFormatter : [default] Windows.UI.Xaml.Data.IValueConverter
    {
        StringFormatter();
    }
}

// StringFormatter.h
#pragma once

#include "StringFormatter.g.h"
#include <sstream>

namespace winrt::Quickstart::implementation
{
    struct StringFormatter : StringFormatterT<StringFormatter>
    {
        StringFormatter() = default;

        Windows::Foundation::IInspectable Convert(Windows::Foundation::IInspectable const& value, Windows::UI::Xaml::Interop::TypeName const& targetType, Windows::Foundation::IInspectable const& parameter, hstring const& language);
        Windows::Foundation::IInspectable ConvertBack(Windows::Foundation::IInspectable const& value, Windows::UI::Xaml::Interop::TypeName const& targetType, Windows::Foundation::IInspectable const& parameter, hstring const& language);
    };
}

namespace winrt::Quickstart::factory_implementation
{
    struct StringFormatter : StringFormatterT<StringFormatter, implementation::StringFormatter>
    {
    };
}

// StringFormatter.cpp
#include "pch.h"
#include "StringFormatter.h"
#include "StringFormatter.g.cpp"

namespace winrt::Quickstart::implementation
{
    Windows::Foundation::IInspectable StringFormatter::Convert(Windows::Foundation::IInspectable const& value, Windows::UI::Xaml::Interop::TypeName const& /* targetType */, Windows::Foundation::IInspectable const& /* parameter */, hstring const& /* language */)
    {
        // Retrieve the value as a Calendar.
        Windows::Globalization::Calendar valueAsCalendar{ value.as<Windows::Globalization::Calendar>() };

        std::wstringstream wstringstream;
        wstringstream << L"Released: ";
        wstringstream << valueAsCalendar.MonthAsNumericString().c_str();
        wstringstream << L"/" << valueAsCalendar.DayAsString().c_str();
        wstringstream << L"/" << valueAsCalendar.YearAsString().c_str();
        return winrt::box_value(hstring{ wstringstream.str().c_str() });
    }

    Windows::Foundation::IInspectable StringFormatter::ConvertBack(Windows::Foundation::IInspectable const& /* value */, Windows::UI::Xaml::Interop::TypeName const& /* targetType */, Windows::Foundation::IInspectable const& /* parameter */, hstring const& /* language */)
    {
        throw hresult_not_implemented();
    }
}
...
public ref class StringFormatter sealed : Windows::UI::Xaml::Data::IValueConverter
{
public:
    virtual Platform::Object^ Convert(Platform::Object^ value, TypeName targetType, Platform::Object^ parameter, Platform::String^ language)
    {
        // Retrieve the value as a Calendar.
        Windows::Globalization::Calendar^ valueAsCalendar = dynamic_cast<Windows::Globalization::Calendar^>(value);

        std::wstringstream wstringstream;
        wstringstream << L"Released: ";
        wstringstream << valueAsCalendar->MonthAsNumericString()->Data();
        wstringstream << L"/" << valueAsCalendar->DayAsString()->Data();
        wstringstream << L"/" << valueAsCalendar->YearAsString()->Data();
        return ref new Platform::String(wstringstream.str().c_str());
    }

    // No need to implement converting back on a one-way binding
    virtual Platform::Object^ ConvertBack(Platform::Object^ value, TypeName targetType, Platform::Object^ parameter, Platform::String^ language)
    {
        throw ref new Platform::NotImplementedException();
    }
};
...

Uyarı

Yukarıdaki C++/WinRT kod listesi için içinde, StringFormatter.idlIValueConverter'ı varsayılan arabirim olarak bildirmek için varsayılan özniteliği kullanırız. Listede StringFormatter yalnızca bir oluşturucuya sahiptir ve hiçbir yöntem içermez, bu nedenle bunun için varsayılan arabirim oluşturulmaz. default özniteliği, StringFormatteriçin örnek üyeler eklemeyecekseniz, IValueConverter yöntemlerini çağırmak için QueryInterface gerekmediğinden en uygun seçenektir. Alternatif olarak, varsayılan IStringFormatter arabiriminin oluşturulmasını isteyebilirsiniz ve bunu yapmak için çalışma zamanı sınıfının kendisinidefault_interface özniteliği ile işaretleyebilirsiniz. Örnek üyelerini çağırmak için QueryInterface gerekmediğinden , StringFormatter'aIValueConverter yöntemlerinden daha sık çağrılan örnek üyeleri eklerseniz bu seçenek en uygun seçenektir.

Artık sayfa kaynağı olarak bir StringFormatter örneği ekleyebilir ve bunu ReleaseDateTime özelliğini görüntüleyen TextBlock bağlamasında kullanabiliriz.

<Page.Resources>
    <local:StringFormatter x:Key="StringFormatterValueConverter"/>
</Page.Resources>
...
<TextBlock Text="{Binding ReleaseDateTime,
    Converter={StaticResource StringFormatterValueConverter},
    ConverterParameter=Released: \{0:d\}}"/>
...

Yukarıda görebileceğiniz gibi, biçimlendirme esnekliği için dönüştürücü parametresi yoluyla dönüştürücüye bir biçim dizesi geçirmek için işaretlemeyi kullanırız. Bu konuda gösterilen kod örneklerinde yalnızca C# değer dönüştürücüsü bu parametreyi kullanır. Ancak, C++stili biçim dizesini dönüştürücü parametresi olarak kolayca geçirebilir ve bunu değer dönüştürücünüzde wprintf veya swprintf gibi bir biçimlendirme işleviyle kullanabilirsiniz.

Sonuç şu şekildedir.

özel biçimlendirme ile tarih görüntüleme

Uyarı

Windows 10, sürüm 1607'den itibaren XAML çerçevesi yerleşik bir Boole-Görünürlük dönüştürücüsü sağlar. Dönüştürücü, true değerini Visibility.Visible numaralandırma değeriyle ve false değerini Visibility.Collapsed ile eşler, böylece bir Visibility özelliğini bir Boole değerine dönüştürücü oluşturmadan bağlayabilirsiniz. Yerleşik dönüştürücüsü kullanmak için uygulamanızın en düşük hedef SDK sürümü 14393 veya üzeri olmalıdır. Uygulamanız Windows 10'un önceki sürümlerini hedeflediğinde kullanamazsınız. Hedef sürümler hakkında daha fazla bilgi için bkz. Sürüm uyarlamalı kod.

Ayrıca bakınız