Veri bağlamaya tanıtma

Tamamlandı

Teknik logo.

Bu derste, geçerli saati gösteren bir uygulama oluşturma hakkında bilgi edinebilirsiniz. Veri bağlamanın temellerini, koddan uygulamanın kullanıcı arabirimine veri alma ve kullanıcı arabiriminde saat güncelleştirmesi için yenileme hakkında bilgi edinebilirsiniz. Bu, sonraki derslerde daha karmaşık veri bağlama görevlerinin temelini oluşturur. Hazırsanız başlayalım!

Teknik logo.

1. Projeyi oluşturma

Henüz çalışmıyorsa 2017'Visual Studio açın. Boş Uygulama (Evrensel Windows) şablonunu kullanarak Yeni bir C# Windows Evrensel projesi oluşturun. DatabindingSample olarak çağırma. Bu, kullanıcı arabirimi ve Veri modülünün tamamı sırasında üzerinde çalışacak projedir.

2017 yeni Visual Studio iletişim kutusunun Project görüntüsü.

Tamam'a Visual Studio, hedef ve en düşük sürüm sürümlerini girmenizi Windows 10 istenir. Bu yalnızca bir alıştırma projesidir ve bunu daha eski bir sürümünü çalıştıran bilgisayarlara dağıtmayı planlaya Windows 10. Bu nedenle, hem en Windows 10, sürüm 1809 hem de hedef sürüm için bir değer seçin ve ardından Tamam'a tıklayın.

2. Saat görüntüsü için TextBlock ekleme

Proje tamamen başlatılmış ve yüklendiğinde, proje çalışma MainPage.xaml alanı içinde çift tıklayarak Çözüm Gezgini.

İpucu

Ekran alanınız azsa, düzenleyiciyi daha düşük çözünürlüklü bir ekranın benzetimini yapmak üzere değiştirmek için sol üst köşedeki açılan liste kullanın. Bu modül için %13,3" Masaüstü (1280x720) %100 ölçek kullanılması önerilir, ancak en rahat hissedeni seçin.

Öğesinin açma ve kapatma etiketleri arasına aşağıdaki satırı Grid ekleyin.

<TextBlock HorizontalAlignment="Right" 
           Margin="10" 
           Text="{x:Bind CurrentTime}" />

Bu, pencerenin sağ üst tarafında 10 birim kenar boşluğuyla yeni bir TextBlock oluşturur. Şimdi TextBlock'un Text'ine bakalım.

Bölümü, Text={x:Bind CurrentTime} veri bağlama ile ilk karşılaşmanızdır. x:Bind , uygulamanın geri kalanıyla birlikte C# koduna derlenmiş bir XAML işaretleme uzantısıdır. Burada özelliğini Text TextBlock özelliğine CurrentTime bağlar. Projeyi şimdi derlemeyi denersanız aşağıdaki hata iletisini alırsınız:

XamlCompiler hatası WMC1110: Geçersiz bağlama yolu 'CurrentTime' : 'CurrentTime' özelliği 'MainPage' türünde bulunamadı

Bu, derleyicinin özelliğinden eksik CurrentTime olduğunu MainPage gösterir. Bu özelliği oluşturdukktan sonra, içeriğin sağ üst TextBlock köşedeki tarafından görüntüleniyor olması gerekir.

Not

UWP, şu şekilde görünen eski bir veri bağlama yöntemini de destekler: Text={Bind CurrentTime} . Bu eski yöntem, 'den biraz farklı {x:Bind} çalışır. En önemlisi, yazım hatası varsa derleme zamanı hataları sunamaz. Bu modülde, yalnızca derleme zamanı hata denetimi sağlayan {x:Bind} yeni bağlama yollarına odaklanacak. Ancak, sürümünden daha olgun değildir ve yeni özellikler alır. Bu nedenle projeyi oluşturmak için en son {x:Bind} {Bind} Windows 10 sürümüne geçerek devam edin.

3. Özelliğini CurrentTime oluşturma

MainPage.xaml.cs'yi açın ve sınıfına aşağıdaki özellik tanımını MainPage ekleyin.

public string CurrentTime => DateTime.Now.ToLongTimeString();

Yukarıdaki söz dizimi hakkında bilgi sahibi değilseniz, bu ifadeye gövdeli üye denir. C# 6.0'da tanıtıldı ve aşağıdakilerin kısa bir kısası:

public string CurrentTime 
{
    get { return DateTime.Now.ToLongTimeString(); }
}

4. Uygulamayı çalıştırma

Uygulamayı şimdi çalıştırırsanız (menüde F5 anahtarını veya Hata Ayıkla / Hata Ayıklamayı Başlat komutunu kullanarak), uygulama derlenmiş ve çalışır. Daha da iyisi çalışıyor gibi görünüyor! Geçerli saat sağ üst köşede görüntülenir.

Saat ile çalışan uygulamanın ekran görüntüsü.

Ancak bir şeyler doğru değildir. Saat güncelleştirmez. Uygulamanın ilk başlatılışında takılmıştır. Tabii ki, uygulamanın ne zaman değeri yenileyeceğimizi nasıl bilir TextBlock ? UWP çalışma zamanına saniyede bir kez güncelleştirilmesini söylememiz gerekir.

5. bağlama modlarını belirtin

{x:Bind} bağlamalar performans için yüksek oranda iyileştirilmiştir. Bu, geliştiricinin açıkça sorulmadığı anlamına gelir. Bu nedenle, bir {x:Bind} bağlama yalnızca bağlama kaynağını (bizim örneğimizde, CurrentTime özelliğini) bir kez değerlendirir. Bu, bağlama olarak adlandırılır OneTime . UWP çerçevesinin Kullanıcı arabirimini güncelleştirmeye devam etmesini istiyorsanız, açıkça başka bir bağlama modu belirtmemiz gerekir: OneWay ya da TwoWay .

TwoWay bağlama modu, C# kodu (Logic) ve Kullanıcı arabirimi arasında çift yönlü bağlamayı gösterir. Bu, Kullanıcı tarafından işlenebilen denetimlere bağladığımızda daha sonra yararlı olacaktır. Ancak, bir TextBlock bağlama bir OneWay bağlama yoludur, çünkü veri değişiklikleri yalnızca kodda olur, hiçbir şekilde kullanıcı arabiriminden değildir.

Bizim için bir OneWay bağlama modu belirtmek için TextBlock , {x:Bind CurrentTime} olarak değiştirin {x:Bind CurrentTime, Mode=OneWay} . İçindeki tüm TextBlock etiketi şöyle Grid görünmelidir.

<TextBlock HorizontalAlignment="Right" 
           Margin="10" 
           Text="{x:Bind CurrentTime, Mode=OneWay}" />

Bu, UWP çalışma zamanına, özellikte yapılan değişiklikleri izlemek için gerekli altyapıyı oluşturmasını CurrentTime ve içinde yansıtmasını sağlar Text TextBlock . Bu ek altyapı, çok büyük miktarda bellek ve CPU döngüsü kaplar ve bu nedenle varsayılan değer değildir.

Uygulamayı şimdi çalıştırırsanız, saat hala güncelleşmez. Özelliğin değiştiğini sisteme bildirmemiz gerekiyor CurrentTime .

6. arabirimi uygulama INotifyPropertyChanged

Bu bildirim arabirim aracılığıyla gerçekleşir INotifyPropertyChanged . Yalnızca tek bir olayla birlikte çok basit bir arabirimdir.

public interface INotifyPropertyChanged
{
    event PropertyChangedEventHandler PropertyChanged;
}

Veri bağlama kaynağı olarak basit bir C# özelliğine sahip olan herhangi bir sınıf, INotifyPropertyChanged arabirimini gerçekleştirmelidir. UI 'nin güncellenmesi gerektiğinde sınıfın olayı tetiklemesi gerekir PropertyChanged . Şimdi, ana sayfa sınıfı bildirimine arayüz ekleyelim.

public sealed partial class MainPage : Page, INotifyPropertyChanged

Ayrıca, bir olayı sınıfına ekleyerek arabirimini de uygulayacağız PropertyChanged .

public event PropertyChangedEventHandler PropertyChanged;

7. PropertyChanged her saniye olayı çağırın

Her şey, her PropertyChanged zaman saat güncelleştirmek istediğimiz olayı çağırmada (yani, her saniye). Bunu yapmak için DispatcherTimer MainPage sınıfında bir nesne bildirelim.

private DispatcherTimer _timer;

Şimdi, InitializeComponent her saniye tetiklendiği şekilde oluşturucuda (çağrıdan sonra) ayarlayalım.

_timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };

_timer.Tick += (sender, o) =>
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentTime)));

_timer.Start();

Yukarıdaki ilk satır, süreölçeri tek saniyelik bir aralıkla oluşturur ve son satır onu başlatır. Zamanlayıcı tetiklendiğinde ne olacağını incelim (ikinci satırda).

PropertyChanged?.Invoke , bir olayın null olup olmadığını denetlemek için toplu, değilse çağırır. Çoğu olay gibi, ilk bağımsız değişken sender ( this ). Etkinliğin ikinci bağımsız değişkeni, PropertyChanged PropertyChangedEventArgs özellik adı olarak bir dize bekleyen bir oluşturucuya sahip olan yeni oluşturulmuş bir nesnedir. Bu nedenle, olaya abone olan aboneler PropertyChanged (Bu durumda, UWP sistemi) güncelleştirilmiş özelliğin adını alır ve buna göre hareket edebilir.

İpucu

Özellik adı için dize sabit değerleri kullanmayın (gibi "CurrentTime" ). Dizenin kendisini kullanmak, Kullanıcı arabirimi güncellenmediği zaman hata ayıklamada sorunlara yol açacak şekilde, yazım hatası verebilir. Ayrıca, masum yeniden adlandırması, dize sabitleri güncelleştirilemeiyorsa hataları ortaya çıkarabilir. Her zaman nameof , yazım hatalarını ve renamings ' i takip eden ifadeyi kullanmak iyi bir uygulamadır.

MainPage. xaml. cs ' nin tamamı aşağıdaki gibi görünmelidir:

namespace DatabindingSample
{
    public sealed partial class MainPage : Page, INotifyPropertyChanged
    {
        private DispatcherTimer _timer;

        public MainPage()
        {
            this.InitializeComponent();
            _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };

            _timer.Tick += (sender, o) =>
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentTime)));

            _timer.Start();
        }

        public string CurrentTime => DateTime.Now.ToLongTimeString();
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

8. uygulamayı çalıştırın

Uygulamayı şimdi çalıştırırsanız saat güncellenir. Tebrikler, ilk veri bağlamayı oluşturdunuz!

9. Özet

Artık, {x:Bind KODDAN UWP uygulamanızın kullanıcı arabirimine veri almanın hızlı ve otomatik bir yolunu oluşturmak için ' nin nasıl kullanılacağını öğrenirsiniz. Bu teknik derleme sırasında denetlenir. Ayrıca, arabirimine alışkın olursunuz INotifyPropertyChanged . Bu arabirim, bir veri bağlantılı özelliği değiştiğinde ve Kullanıcı arabiriminin güncellenmesi gerektiğinde, uygulamanızın UWP çerçevesini bilgilendirmesini sağlar.

Teknik logo.

1. projeyi oluşturma

zaten çalışmıyorsa Visual Studio 2017 ' i açın. WPF uygulaması (.NET Framework) şablonunu kullanarak yeni bir C# Windows Universal projesi oluşturun. DatabindingSampleWPF çağırın ve sonra Tamam' ı seçin. Bu, tüm Kullanıcı arabirimi ve veri modülü boyunca birlikte çalışacaksınız.

Visual Studio 2017 yeni Project iletişim kutusunun ekran görüntüsü.

2. saat sınıfını oluşturma

Görevimiz geçerli zamanı görüntülemesi gerektiğinden, önce bir sınıf oluşturmak mantıklı olur Clock . DatabindingSampleWPF Çözüm Gezgini' de projeye sağ tıklayın, Ekle/sınıf' i seçin ve Clock sınıf ' adı olarak girin.

Aşağıdaki kodu yeni oluşturulan dosyaya kopyalayın:

using System;

namespace DatabindingSampleWPF
{
    public class Clock
    {
        public string CurrentTime => DateTime.Now.ToLongTimeString();
    }
}

Özelliği için yukarıdaki sözdizimine alışkın değilseniz CurrentTime , bu, ifade eden bir üye olarak adlandırılır. C# 6,0 ' de tanıtılmıştı ve aşağıdakiler için bir toplu özelliktir:

public string CurrentTime 
{
    get { return DateTime.Now.ToLongTimeString(); }
}

Görebileceğiniz gibi, tüm sınıf o kadar Clock string geçerli zamanı uzun saat biçiminde döndüren basit bir özelliktir. Sonraki adım uygulamanın içinde zamanı görüntülemektir.

3. saat gösterimi için TextBlock ekleyin

MainWindow.xamlVisual Studio açıksa, onun sekmesini seçin. Aksi takdirde, Çözüm Gezgini çift tıklayarak açabilirsiniz.

Öğesinin açılış ve kapanış etiketleri arasına aşağıdaki satırı ekleyin Grid .

<TextBlock HorizontalAlignment="Right" 
           VerticalAlignment="Top"
           Margin="10" 
           Text="{Binding CurrentTime}">
    <TextBlock.DataContext>
        <local:Clock/>
    </TextBlock.DataContext>
</TextBlock>

Bu işlem, pencerenin sağ üst tarafında, kenarından 10 birim kenar boşluğu ile yeni bir TextBlock oluşturur.

Text="{Binding CurrentTime}"Bölüm, veri bağlamasıyla ilk kez karşılaştınız. {Binding} bir XAML biçimlendirme uzantısıdır. Burada, öğesinin özelliğini özelliğine bağlar, Text TextBlock CurrentTime ancak CurrentTime hangi nesnenin özelliğine?

Veri bağlamasının başvurduğu nesne, öğesinin ' de oluşturulur DataContext TextBlock . Bu nedenle, Yukarıdaki XAML kodu yalnızca bir denetim oluşturmayabilir TextBlock , ancak aynı zamanda bir Clock nesnesi oluşturur. Ayrıca kod, Text öğesinin özelliğini TextBlock CurrentTime Clock yeni oluşturduğu nesnenin özelliğine bağlar. CurrentTimeÖzelliği bağlamanın kaynağı olarak adlandırılır, ancak Text özellik bağlamanın hedefi olarak adlandırılır.

4. uygulamayı çalıştırın

Uygulamayı şimdi başlatırsanız (menüdeki F5 tuşunu veya hata ayıklama/hata ayıklamayı Başlat komutunu kullanarak), uygulama derlenir ve çalışır. Ne kadar iyi olan özellikler de çalışır! Geçerli saat sağ üst köşede görüntülenir.

Çalışan uygulamanın saatiyle ilgili ekran görüntüsü.

Ancak bir şey gerçekten doğru değildir. Saat güncelleştirmez. Uygulamanın ilk başlatılışında takılmıştır. Tabii ki, uygulamanın ne zaman değeri yenileyeceğimizi nasıl bilir TextBlock ? WPF çalışma zamanına, bir saniyede bir kez güncelleştirilmesini söylememiz gerekir.

Diğer bir deyişle, özelliğin değiştiğini sisteme bildirmemiz gerekir CurrentTime .

5. arabirimi uygulama INotifyPropertyChanged

Bu bildirim arabirim aracılığıyla gerçekleşir INotifyPropertyChanged . Yalnızca tek bir olayla birlikte çok basit bir arabirimdir.

public interface INotifyPropertyChanged
{
    event PropertyChangedEventHandler PropertyChanged;
}

Veri bağlama kaynağı olarak basit bir C# özelliğine sahip olan herhangi bir sınıf, INotifyPropertyChanged arabirimini gerçekleştirmelidir. UI 'nin güncellenmesi gerektiğinde sınıfın olayı tetiklemesi gerekir PropertyChanged . Şimdi de bir arabirim Clock sınıfı bildirimine ekleyin.

using System.ComponentModel;

public class Clock : INotifyPropertyChanged
{

Ayrıca, bir olayı sınıfına ekleyerek arabirimini de uygulayacağız PropertyChanged .

public event PropertyChangedEventHandler PropertyChanged;

6. PropertyChanged her saniye olayı çağırın

Her şey, her PropertyChanged zaman saat güncelleştirmek istediğimiz olayı çağırmada (yani, her saniye). Bunu yapmak için System.Windows.Threading ad alanını s öğesine ekleyelim using ve sınıfta bir nesne bildirelim DispatcherTimer Clock .

private DispatcherTimer _timer;

Şimdi bu ayarı oluşturucuda ayarlayın, böylece her saniye başlatılır.

public Clock()
{
    _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };

    _timer.Tick += (sender, o) => PropertyChanged?.Invoke(this,
            new PropertyChangedEventArgs(nameof(CurrentTime)));

    _timer.Start();
}

Oluşturucudaki ilk satır, süreölçeri tek saniyelik bir aralıkla oluşturur ve son satır onu başlatır. Zamanlayıcı tetiklendiğinde ne olacağını incelim (ikinci satırda).

PropertyChanged?.Invoke , bir olayın null olup olmadığını denetlemek için toplu, değilse çağırır. Çoğu olay gibi, ilk bağımsız değişken sender ( this ). Etkinliğin ikinci bağımsız değişkeni, PropertyChanged PropertyChangedEventArgs özellik adı olarak bir dize bekleyen bir oluşturucuya sahip olan yeni oluşturulmuş bir nesnedir. Bu nedenle, olaya abone PropertyChanged olan aboneler (Bu durumda, WPF sistemi) güncelleştirilmiş özelliğin adını alır ve buna göre hareket edebilir.

İpucu

Özellik adı için dize sabit değerleri kullanmayın (gibi "CurrentTime" ). Dizenin kendisini kullanmak, Kullanıcı arabirimi güncellenmediği zaman hata ayıklamada sorunlara yol açacak şekilde, yazım hatası verebilir. Ayrıca, masum yeniden adlandırması, dize sabitleri güncelleştirilemeiyorsa hataları ortaya çıkarabilir. Her zaman nameof , yazım hatalarını ve renamings ' i takip eden ifadeyi kullanmak iyi bir uygulamadır.

Tüm Clock. cs aşağıdaki gibi görünmelidir:

namespace DatabindingSampleWPF
{
    using System;
    using System.ComponentModel;
    using System.Windows.Threading;

    public class Clock : INotifyPropertyChanged
    {
        private DispatcherTimer _timer;

        public string CurrentTime => DateTime.Now.ToLongTimeString();

        public event PropertyChangedEventHandler PropertyChanged;

        public Clock()
        {
            // setup _timer to refresh CurrentTime
            _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) };
            _timer.Tick += (sender, o) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentTime)));
            _timer.Start();
        }
    }
}

7. uygulamayı çalıştırın

Uygulamayı şimdi çalıştırırsanız saat güncellenir. İlk veri bağlamayı oluşturdunuz!

8. Özet

Artık, {Binding} KODDAN WPF uygulamanızın kullanıcı arabirimine veri almanın hızlı ve otomatik bir yolunu oluşturmak için nasıl kullanılacağını öğrenirsiniz. Ayrıca, arabirimine alışkın olursunuz INotifyPropertyChanged . Bu arabirim, bir veri bağlantılı özelliği değiştirildiğinde ve Kullanıcı arabiriminin güncellenmesi gerektiğinde uygulamanızın WPF çerçevesini bilgilendirmesini sağlar.