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.
Uyarı
Visual Studio 2022 çalıştırıyorsanız, bu öğretici için 17.3 veya sonraki bir sürümü kullandığınızdan emin olun.
Bu öğreticide, Visual Studio'da veri uygulaması üzerinden temel formlar oluşturma gösterilmektedir. Uygulama SQL Server LocalDB, Northwind veritabanı, Entity Framework 6 (Entity Framework Core değil) ve .NET Framework için Windows Presentation Foundation (WPF) kullanır (.NET Core veya .NET 5 veya üzerini kullanmaz). Ana-ayrıntı görünümüyle temel veri bağlamanın nasıl yapılacağını gösterir ve aşağıdakileri gerçekleştiren düğmelere sahip özel bir BindingNavigator denetimi içerir: ilke git, öncekiye git, sonrakine git, son git, sil, ekle, yeni sırala, güncelleştir ve iptal et.
Bu öğretici, Visual Studio'da veri araçlarını kullanmaya odaklanır ve temel alınan teknolojileri ayrıntılı olarak açıklamaya çalışmaz. Genişletilebilir Uygulama Biçimlendirme Dili (XAML), Entity Framework ve SQL hakkında temel bir bilginiz olduğu varsayılır. Bu öğreticideki kod WPF uygulamaları için standart olan Model-View-ViewModel (MVVM) mimarisini göstermese de, birkaç değişiklikle kodu kendi MVVM uygulamanıza kopyalayabilirsiniz.
Bu öğreticinin son kodunu görüntülemek için bkz. Visual Studio öğretici örnekleri - EF6.
Bu eğitimde, siz:
- Northwind'i yükleme ve northwind'e bağlanma
- WPF uygulama projesini yapılandırma
- ADO.NET varlık veri modelini oluşturma
- Veriler modeli XAML sayfasına bağlar
- Sayfa tasarımını ayarla ve kılavuz ekle
- Gezinmek, eklemek, güncelleştirmek ve silmek için düğme ekleme
- WPF uygulamasını çalıştırma
Önkoşullar
.NET Masaüstü Geliştirme iş yükü ve Windows Communication Foundation bileşeni yüklü Visual Studio. Yüklemek için:
- Visual Studio Yükleyicisi uygulamasını açın veya Visual Studio menüsünde Araçlar>Araçları ve Özellikleri Al'ı seçin.
- Visual Studio Yükleyicisi'nde, değiştirmek istediğiniz Visual Studio sürümünün yanındaki Değiştir'i seçin.
- Tek tek bileşenler sekmesini seçin ve ardından Geliştirme etkinlikleri'nin altında Windows Communication Foundation'ı seçin.
- Değiştir'i seçin.
SQL Server Express LocalDB. SQL Server Express LocalDB'niz yoksa SQL Server indirme sayfasındanyükleyebilirsiniz. Alternatif olarak, visual studio yükleyicisi uygulamasını tek bir bileşen olarak da yükleyebilirsiniz.
SQL Server Nesne Gezgini. Yüklemek için Visual Studio Yükleyicisi uygulamasında Veri depolama ve işleme iş yükünü yükleyin.
Entity Framework 6 araçları. Bu genellikle .NET Dektop Geliştirme iş yükünü yüklediğinizde yüklenir.
Northwind'i yükleme ve northwind'e bağlanma
Aşağıdaki örnekte SQL Server Express LocalDB ve Northwind örnek veritabanı kullanılmaktadır. Bu ürünün ADO.NET veri sağlayıcısı Entity Framework'i destekliyorsa, diğer SQL veritabanı ürünleriyle de çalışmalıdır.
Aşağıdaki adımları izleyerek Northwind örnek veritabanını yükleyin:
Visual Studio'da, Görünüm menüsünden SQL Server Nesne Gezgini penceresini açın. SQL Server düğümünü genişletin. LocalDB örneğinize sağ tıklayın ve Yeni Sorgu'yu seçin.
Sorgu düzenleyicisi penceresi açılır.
Northwind Transact-SQL (T-SQL) betiğini panonuza kopyalayın.
T-SQL betiğini sorgu düzenleyicisine yapıştırın ve yürüt'e tıklayın.
T-SQL betik sorgusu Northwind veritabanını oluşturur ve verilerle doldurur.
Northwind veritabanı için yeni bağlantılar ekleyin.
WPF uygulama projesini yapılandırma
WPF uygulama projesini yapılandırmak için şu adımları izleyin:
Visual Studio'da yeni bir C# WPF Uygulaması (.NET Framework) projesi oluşturun.
Entity Framework 6 için NuGet paketini ekleyin. Çözüm Gezgini'da proje düğümünü seçin. Ana menüde NuGet Paketlerini
NuGet Paket Yöneticisi'ndeGözat bağlantısını seçin. EntityFramework paketini arayın ve seçin. Sağ bölmede Yükle'yi seçin ve istemleri izleyin.
Çıkış penceresi ilerleme durumunu görüntüler ve yükleme tamamlandığında size bildirir.
Artık Northwind veritabanını temel alan bir model oluşturmak için Visual Studio'yu kullanabilirsiniz.
ADO.NET varlık veri modelini oluşturma
ADO.NET varlık veri modelini oluşturmak için şu adımları izleyin:
Çözüm Gezgini'nde WPF Uygulaması proje düğümüne sağ tıklayın veYeni Öğe Ekle'yi> seçin. Sol bölmede, C# düğümü altında Veri'yi seçin ve orta bölmede Varlık Veri Modeli'ni ADO.NET seçin.
Name için Northwind_model girin ve Ekle seçin.
Varlık Veri Modeli Sihirbazı'ndaveritabanından EF Designer'ı ve ardından İleri'yi seçin.
Veri Bağlantınızı Seçin bölümünde LocalDB Northwind bağlantınızı (örneğin, (localdb)\MSSQLLocalDB) ve ardından İleri'yi seçin.
Bağlantı görmüyorsanız:
Yeni Bağlantı'yı seçin. Bağlantı Özellikleri iletişim kutusunda Veri kaynağı olarak Microsoft SQL Server seçilmediyse Değiştir'i seçin. Veri Kaynağı Seç iletişim kutusunda Microsoft SQL Server'ı ve ardından Tamam'ı seçin.
Bağlantı Özellikleri iletişim kutusunda Sunucu adı olarak (localdb)\MSSQLLocalDB girin.
Veritabanı adı seçin veya girin için Northwind'i ve ardından Tamam'ı seçin.
Veri Bağlantınızı Seçin bölümünde LocalDB Northwind bağlantınızı seçin ve İleri'yi seçin.
İstenirse, kullanmakta olduğunuz Entity Framework sürümünü seçin ve ardından İleri'yi seçin.
Sihirbazın sonraki sayfasında, Entity Framework modeline eklenecek tabloları, saklı yordamları ve diğer veritabanı nesnelerini seçin. Ağaç görünümünde tablolar düğümünü altındaki dbo düğümünü genişletin. Müşteriler, Sipariş Ayrıntıları ve Siparişler'i seçin. Varsayılan değerleri işaretli bırakın ve Son'u seçin.
Sihirbaz, Entity Framework modelini temsil eden ve Visual Studio’nun WPF kullanıcı arabirimine veri bağlama işlevi gerçekleştirdiği C# sınıflarını oluşturur. Projenizde aşağıdaki dosyaları oluşturur:
Dosya,
.edmxsınıfları veritabanındaki nesnelerle ilişkilendiren ilişkileri ve diğer meta verileri açıklar.Dosyalar
.tt, model üzerinde çalışan kodu oluşturan ve değişiklikleri veritabanına kaydeden T4 şablonlarıdır.
Bu dosyalar Çözüm Gezgini'ndeNorthwind_model düğümü altında görünür:
Dosya için
.edmxForm Tasarımcısı bu öğreticide kullanılmaz, ancak bunu kullanarak modeldeki belirli özellikleri ve ilişkileri değiştirebilirsiniz.
Dosyalar .tt genel amaçlıdır ve nesne gerektiren ObservableCollection WPF veri bağlaması ile çalışmak için bunlardan birini düzenlemeniz gerekir. Şu adımları izleyin:
Çözüm Gezgini'ndeNorthwind_model.tt dosyasını bulana kadar Northwind_model düğümünü genişletin. Bu dosyaya çift tıklayın ve aşağıdaki düzenlemeleri yapın:
öğesinin iki örneğini ICollection ile ObservableCollection<T>değiştirin.
Satır 51'e yakın yerdeki ilk HashSet<T>'i ObservableCollection<T> ile değiştirin. HashSet'in ikinci oluşumunu değiştirmeyin.
öğesinin tek oluşumunu System.Collections.Generic (431. satırın yakınında) ile System.Collections.ObjectModeldeğiştirin.
Projeyi derlemek ve çalıştırmak için F5 tuşuna basın. Uygulama ilk kez çalıştırıldığında, model sınıfları veri kaynakları sihirbazı tarafından görülebilir.
Artık verileri görüntüleyebilmeniz, gezinebilmeniz ve değiştirebilmeniz için bu modeli XAML sayfasına bağlamaya hazırsınız.
Veriler modeli XAML sayfasına bağlar
Kendi veri bağlama kodunuzu yazmak mümkün olsa da Visual Studio'nun sizin yerinize yazmasına izin vermek daha kolaydır. Bunu yapmak için şu adımları izleyin:
Veri Kaynağı Yapılandırma Sihirbazı'nı görüntülemek için ana >Yeni veri kaynağı ekle'yi seçin. Veritabanına değil model sınıflarına bağlandığınız için Nesne'yi seçin. sonrakiseçin.
Projenizin düğümünü genişletin, Customer nesnesini seçin ve ardından Son'u seçin. Order nesnelerinin kaynakları, Müşteri'dekiSiparişler gezinti özelliğinden otomatik olarak oluşturulur.
Çözüm Gezgini'nde projenizdeki MainWindow.xaml öğesine çift tıklayarak XAML'yi düzenleyin.
TitlemainWindow değerini daha açıklayıcı bir değer olarak değiştirin ve değerini 600 ve 800 olarak artırınHeightWidth(gerekirse bu değerleri daha sonra değiştirebilirsiniz).Bu üç satır tanımını ana kılavuza, gezinti düğmeleri için bir satır, müşterinin ayrıntıları için bir satır ve siparişlerini gösteren kılavuz için bir satır ekleyin:
<Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions>
Ardından, sınıfındaki Customers her özelliği kendi metin kutusunda görüntülersiniz. Şu adımları izleyin:
Çözüm Gezgini'ndeMainWindow.xaml dosyasına çift tıklayarak tasarımcıda açın.
Veri Kaynakları sekmesi, Araç Kutusu'nun yakınındaki Visual Studio'nun sol bölmesinde görünür.
Veri Kaynakları penceresini açmak için Veri Kaynakları sekmesini seçin veya menüdenDiğer Windows>Veri Kaynaklarını> seçin.
Veri Kaynakları'ndaMüşteriler'i ve ardından açılan listeden Ayrıntılar'ı seçin.
Düğümü tasarım alanının orta satırına sürükleyin. Kaybederseniz, daha sonra XAML’de elle satırı belirleyebilir ve
Grid.Row="1"seçebilirsiniz.Varsayılan olarak, denetimler bir kılavuz öğesine dikey olarak yerleştirilir, ancak formda istediğiniz gibi düzenleyebilirsiniz. Örneğin, Ad metin kutusunu adresin üzerine yerleştirebilirsiniz. Bu öğreticinin örnek uygulaması alanları yeniden sıralar ve bunları iki sütun halinde yeniden düzenler.
XAML görünümünde artık üst kılavuzun 1. satırında (orta satır) yeni
Gridbir öğe görebilirsiniz. Üst kılavuz,DataContextöğesine ait olan CollectionViewSource'e başvuran birWindows.Resourcesözniteliğine sahiptir. Bu veri bağlamı göz önüne alındığında, ilk metin kutusu Adres'e bağlandığında, bu ad geçerliAddressnesnesindekiCustomerözelliğineCollectionViewSourceeşlenir.<Grid DataContext="{StaticResource customerViewSource}">Nesnenin
Ordersınıfının özelliğini formun alt yarısına sürükleyin, böylece tasarımcı bunuCustomers2. satırına yerleştirir.Bir müşteri formun üst yarısında görünür olduğunda, siparişlerini alt yarısında görmek istersiniz. Siparişleri tek bir kılavuz görünümü denetiminde gösterirsiniz. Ana-ayrıntı veri bağlamanın beklendiği gibi çalışması için, ayrı bir
Ordersdüğüm yerineCustomerssınıfındakiOrdersözelliğine bağlanmanız önemlidir.
Visual Studio artık kullanıcı arabirimi denetimlerini modeldeki olaylara bağlayan tüm bağlama kodunu oluşturur.
Bazı verileri görmek için modeli doldurmak için kod yazın.
MainWindow.xaml.cs'e gidin ve veri bağlamı içinMainWindowsınıfına bir veri üyesi ekleyin.Sizin için oluşturulan bu nesne, modeldeki değişiklikleri ve olayları izleyen bir denetim gibi davranır.
Müşteriler ve siparişler için veri üyelerini ve ilişkili oluşturucu başlatma mantığını mevcut oluşturucuya
CollectionViewSourceekleyinMainWindow(). Sınıfın ilk bölümü şöyle görünmelidir:public partial class MainWindow : Window { NorthwindEntities context = new NorthwindEntities(); CollectionViewSource custViewSource; CollectionViewSource ordViewSource; public MainWindow() { InitializeComponent(); custViewSource = ((CollectionViewSource)(FindResource("customerViewSource"))); ordViewSource = ((CollectionViewSource)(FindResource("customerOrdersViewSource"))); DataContext = this; }Yoksa,
usingiçin,System.Data.Entityuzantı yöntemini kapsama getirmek amacıyla birLoadyönerge ekleyin.using System.Data.Entity;Aşağı kaydırın ve olay işleyicisini
Window_Loadedbulun. Visual Studio'da birCollectionViewSourcenesne eklendiğine dikkat edin. Bu nesne, modeli oluştururken seçtiğiniz nesneyi temsil ederNorthwindEntities. Zaten eklediğiniz için buraya ihtiyacınız yoktur. yönteminin şuna benzemesi için içindekiWindow_Loadedkodu değiştirin:private void Window_Loaded(object sender, RoutedEventArgs e) { // Load is an extension method on IQueryable, // defined in the System.Data.Entity namespace. // This method enumerates the results of the query, // similar to ToList but without creating a list. // When used with Linq to Entities, this method // creates entity objects and adds them to the context. context.Customers.Load(); // After the data is loaded, call the DbSet<T>.Local property // to use the DbSet<T> as a binding source. custViewSource.Source = context.Customers.Local; }F5 tuşuna basın.
İlk müşterinin
CollectionViewSourceve siparişlerinin ayrıntılarını veri tablosunda görmeniz gerekir. Biçimlendirmeyi sonraki bölümde düzelteceksiniz. Ayrıca diğer kayıtları görüntülemenin ve temel oluşturma, okuma, güncelleştirme ve silme (CRUD) işlemlerini gerçekleştirmenin bir yolunu da oluşturabilirsiniz.
Sayfa tasarımını ayarlama ve yeni müşteriler ve siparişler için kılavuzlar ekleme
Visual Studio tarafından üretilen varsayılan düzenleme uygulamanız için ideal olmadığından, kodunuz içine kopyalamak için son XAML'yi burada sağlarız. Kullanıcının yeni bir müşteri veya sipariş eklemesini sağlamak için bazı kılavuzlara da ihtiyacınız vardır.
Yeni müşteri ve sipariş eklemek için, veriye bağlı CollectionViewSourceolmayan ayrı bir metin kutusu kümesi oluşturun. İşleyici yöntemlerinde Görünür özelliğini ayarlayarak kullanıcının her an hangi kılavuzu göreceğini kontrol edebilirsiniz. Son olarak, kullanıcının tek bir siparişi silmesini sağlamak için Siparişler kılavuzundaki her satıra bir Sil düğmesi eklersiniz.
MainWindow.xamlöğesini açın veWindows.Resourcesöğesine aşağıdaki stilleri ekleyin:<Style x:Key="Label" TargetType="{x:Type Label}" BasedOn="{x:Null}"> <Setter Property="HorizontalAlignment" Value="Left"/> <Setter Property="VerticalAlignment" Value="Center"/> <Setter Property="Margin" Value="3"/> <Setter Property="Height" Value="23"/> </Style> <Style x:Key="CustTextBox" TargetType="{x:Type TextBox}" BasedOn="{x:Null}"> <Setter Property="HorizontalAlignment" Value="Right"/> <Setter Property="VerticalAlignment" Value="Center"/> <Setter Property="Margin" Value="3"/> <Setter Property="Height" Value="26"/> <Setter Property="Width" Value="120"/> </Style>Dış kılavuzun tamamını şu işaretlemeyle değiştirin:
<Grid> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="existingCustomerGrid" Grid.Row="1" HorizontalAlignment="Left" Margin="5" Visibility="Visible" VerticalAlignment="Top" Background="AntiqueWhite" DataContext="{StaticResource customerViewSource}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" MinWidth="233"/> <ColumnDefinition Width="Auto" MinWidth="397"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Label Content="Customer ID:" Grid.Row="0" Style="{StaticResource Label}"/> <TextBox x:Name="customerIDTextBox" Grid.Row="0" Style="{StaticResource CustTextBox}" Text="{Binding CustomerID, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Company Name:" Grid.Row="1" Style="{StaticResource Label}"/> <TextBox x:Name="companyNameTextBox" Grid.Row="1" Style="{StaticResource CustTextBox}" Text="{Binding CompanyName, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Contact Name:" Grid.Row="2" Style="{StaticResource Label}"/> <TextBox x:Name="contactNameTextBox" Grid.Row="2" Style="{StaticResource CustTextBox}" Text="{Binding ContactName, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Contact title:" Grid.Row="3" Style="{StaticResource Label}"/> <TextBox x:Name="contactTitleTextBox" Grid.Row="3" Style="{StaticResource CustTextBox}" Text="{Binding ContactTitle, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Address:" Grid.Row="4" Style="{StaticResource Label}"/> <TextBox x:Name="addressTextBox" Grid.Row="4" Style="{StaticResource CustTextBox}" Text="{Binding Address, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="City:" Grid.Column="1" Grid.Row="0" Style="{StaticResource Label}"/> <TextBox x:Name="cityTextBox" Grid.Column="1" Grid.Row="0" Style="{StaticResource CustTextBox}" Text="{Binding City, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Country:" Grid.Column="1" Grid.Row="1" Style="{StaticResource Label}"/> <TextBox x:Name="countryTextBox" Grid.Column="1" Grid.Row="1" Style="{StaticResource CustTextBox}" Text="{Binding Country, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Fax:" Grid.Column="1" Grid.Row="2" Style="{StaticResource Label}"/> <TextBox x:Name="faxTextBox" Grid.Column="1" Grid.Row="2" Style="{StaticResource CustTextBox}" Text="{Binding Fax, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Phone:" Grid.Column="1" Grid.Row="3" Style="{StaticResource Label}"/> <TextBox x:Name="phoneTextBox" Grid.Column="1" Grid.Row="3" Style="{StaticResource CustTextBox}" Text="{Binding Phone, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Postal Code:" Grid.Column="1" Grid.Row="4" VerticalAlignment="Center" Style="{StaticResource Label}"/> <TextBox x:Name="postalCodeTextBox" Grid.Column="1" Grid.Row="4" Style="{StaticResource CustTextBox}" Text="{Binding PostalCode, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Region:" Grid.Column="1" Grid.Row="5" Style="{StaticResource Label}"/> <TextBox x:Name="regionTextBox" Grid.Column="1" Grid.Row="5" Style="{StaticResource CustTextBox}" Text="{Binding Region, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> </Grid> <Grid x:Name="newCustomerGrid" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5" DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=newCustomer, UpdateSourceTrigger=Explicit}" Visibility="Collapsed" Background="CornflowerBlue"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" MinWidth="233"/> <ColumnDefinition Width="Auto" MinWidth="397"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Label Content="Customer ID:" Grid.Row="0" Style="{StaticResource Label}"/> <TextBox x:Name="add_customerIDTextBox" Grid.Row="0" Style="{StaticResource CustTextBox}" Text="{Binding CustomerID, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Company Name:" Grid.Row="1" Style="{StaticResource Label}"/> <TextBox x:Name="add_companyNameTextBox" Grid.Row="1" Style="{StaticResource CustTextBox}" Text="{Binding CompanyName, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true }"/> <Label Content="Contact Name:" Grid.Row="2" Style="{StaticResource Label}"/> <TextBox x:Name="add_contactNameTextBox" Grid.Row="2" Style="{StaticResource CustTextBox}" Text="{Binding ContactName, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Contact title:" Grid.Row="3" Style="{StaticResource Label}"/> <TextBox x:Name="add_contactTitleTextBox" Grid.Row="3" Style="{StaticResource CustTextBox}" Text="{Binding ContactTitle, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Address:" Grid.Row="4" Style="{StaticResource Label}"/> <TextBox x:Name="add_addressTextBox" Grid.Row="4" Style="{StaticResource CustTextBox}" Text="{Binding Address, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="City:" Grid.Column="1" Grid.Row="0" Style="{StaticResource Label}"/> <TextBox x:Name="add_cityTextBox" Grid.Column="1" Grid.Row="0" Style="{StaticResource CustTextBox}" Text="{Binding City, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Country:" Grid.Column="1" Grid.Row="1" Style="{StaticResource Label}"/> <TextBox x:Name="add_countryTextBox" Grid.Column="1" Grid.Row="1" Style="{StaticResource CustTextBox}" Text="{Binding Country, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Fax:" Grid.Column="1" Grid.Row="2" Style="{StaticResource Label}"/> <TextBox x:Name="add_faxTextBox" Grid.Column="1" Grid.Row="2" Style="{StaticResource CustTextBox}" Text="{Binding Fax, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Phone:" Grid.Column="1" Grid.Row="3" Style="{StaticResource Label}"/> <TextBox x:Name="add_phoneTextBox" Grid.Column="1" Grid.Row="3" Style="{StaticResource CustTextBox}" Text="{Binding Phone, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Postal Code:" Grid.Column="1" Grid.Row="4" VerticalAlignment="Center" Style="{StaticResource Label}"/> <TextBox x:Name="add_postalCodeTextBox" Grid.Column="1" Grid.Row="4" Style="{StaticResource CustTextBox}" Text="{Binding PostalCode, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Region:" Grid.Column="1" Grid.Row="5" Style="{StaticResource Label}"/> <TextBox x:Name="add_regionTextBox" Grid.Column="1" Grid.Row="5" Style="{StaticResource CustTextBox}" Text="{Binding Region, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> </Grid> <Grid x:Name="newOrderGrid" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5" DataContext="{Binding Path=newOrder, Mode=TwoWay}" Visibility="Collapsed" Background="LightGreen"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" MinWidth="233"/> <ColumnDefinition Width="Auto" MinWidth="397"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Label Content="New Order Form" FontWeight="Bold"/> <Label Content="Employee ID:" Grid.Row="1" Style="{StaticResource Label}"/> <TextBox x:Name="add_employeeIDTextBox" Grid.Row="1" Style="{StaticResource CustTextBox}" Text="{Binding EmployeeID, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Order Date:" Grid.Row="2" Style="{StaticResource Label}"/> <DatePicker x:Name="add_orderDatePicker" Grid.Row="2" HorizontalAlignment="Right" Width="120" SelectedDate="{Binding OrderDate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, UpdateSourceTrigger=PropertyChanged}"/> <Label Content="Required Date:" Grid.Row="3" Style="{StaticResource Label}"/> <DatePicker x:Name="add_requiredDatePicker" Grid.Row="3" HorizontalAlignment="Right" Width="120" SelectedDate="{Binding RequiredDate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, UpdateSourceTrigger=PropertyChanged}"/> <Label Content="Shipped Date:" Grid.Row="4" Style="{StaticResource Label}"/> <DatePicker x:Name="add_shippedDatePicker" Grid.Row="4" HorizontalAlignment="Right" Width="120" SelectedDate="{Binding ShippedDate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, UpdateSourceTrigger=PropertyChanged}"/> <Label Content="Ship Via:" Grid.Row="5" Style="{StaticResource Label}"/> <TextBox x:Name="add_ShipViaTextBox" Grid.Row="5" Style="{StaticResource CustTextBox}" Text="{Binding ShipVia, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> <Label Content="Freight" Grid.Row="6" Style="{StaticResource Label}"/> <TextBox x:Name="add_freightTextBox" Grid.Row="6" Style="{StaticResource CustTextBox}" Text="{Binding Freight, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/> </Grid> <DataGrid x:Name="ordersDataGrid" SelectionUnit="Cell" SelectionMode="Single" AutoGenerateColumns="False" CanUserAddRows="false" IsEnabled="True" EnableRowVirtualization="True" Width="auto" ItemsSource="{Binding Source={StaticResource customerOrdersViewSource}}" Margin="10,10,10,10" Grid.Row="2" RowDetailsVisibilityMode="VisibleWhenSelected"> <DataGrid.Columns> <DataGridTemplateColumn> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Content="Delete" Command="{StaticResource DeleteOrderCommand}" CommandParameter="{Binding}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn x:Name="customerIDColumn" Binding="{Binding CustomerID}" Header="Customer ID" Width="SizeToHeader"/> <DataGridTextColumn x:Name="employeeIDColumn" Binding="{Binding EmployeeID}" Header="Employee ID" Width="SizeToHeader"/> <DataGridTextColumn x:Name="freightColumn" Binding="{Binding Freight}" Header="Freight" Width="SizeToHeader"/> <DataGridTemplateColumn x:Name="orderDateColumn" Header="Order Date" Width="SizeToHeader"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <DatePicker SelectedDate="{Binding OrderDate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, UpdateSourceTrigger=PropertyChanged}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn x:Name="orderIDColumn" Binding="{Binding OrderID}" Header="Order ID" Width="SizeToHeader"/> <DataGridTemplateColumn x:Name="requiredDateColumn" Header="Required Date" Width="SizeToHeader"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <DatePicker SelectedDate="{Binding RequiredDate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, UpdateSourceTrigger=PropertyChanged}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn x:Name="shipAddressColumn" Binding="{Binding ShipAddress}" Header="Ship Address" Width="SizeToHeader"/> <DataGridTextColumn x:Name="shipCityColumn" Binding="{Binding ShipCity}" Header="Ship City" Width="SizeToHeader"/> <DataGridTextColumn x:Name="shipCountryColumn" Binding="{Binding ShipCountry}" Header="Ship Country" Width="SizeToHeader"/> <DataGridTextColumn x:Name="shipNameColumn" Binding="{Binding ShipName}" Header="Ship Name" Width="SizeToHeader"/> <DataGridTemplateColumn x:Name="shippedDateColumn" Header="Shipped Date" Width="SizeToHeader"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <DatePicker SelectedDate="{Binding ShippedDate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true, UpdateSourceTrigger=PropertyChanged}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn x:Name="shipPostalCodeColumn" Binding="{Binding ShipPostalCode}" Header="Ship Postal Code" Width="SizeToHeader"/> <DataGridTextColumn x:Name="shipRegionColumn" Binding="{Binding ShipRegion}" Header="Ship Region" Width="SizeToHeader"/> <DataGridTextColumn x:Name="shipViaColumn" Binding="{Binding ShipVia}" Header="Ship Via" Width="SizeToHeader"/> </DataGrid.Columns> </DataGrid> </Grid>
Gezinmek, eklemek, güncelleştirmek ve silmek için düğme ekleme
Windows Forms uygulamasında, veritabanındaki satırlarda gezinmek ve temel CRUD işlemleri yapmak için düğmeler içeren bir nesne sağlanır BindingNavigator . WPF bir BindingNavigatorsağlamasa da, yatay StackPaneliçinde düğmeler oluşturarak ve düğmeleri arka planda kod dosyasındaki yöntemlere bağlı komutlarla ilişkilendirerek kolayca bir tane oluşturabilirsiniz.
Komut mantığının dört bölümü vardır:
- Komutlar
- Bağlamalar
- Düğme
- Arka planda kod içindeki komut işleyicileri
XAML'de komut, bağlama ve düğme ekleme
MainWindow.xamldosyasında, komutları öğesininWindows.Resourcesiçine aşağıdaki gibi ekleyin:<RoutedUICommand x:Key="FirstCommand" Text="First"/> <RoutedUICommand x:Key="LastCommand" Text="Last"/> <RoutedUICommand x:Key="NextCommand" Text="Next"/> <RoutedUICommand x:Key="PreviousCommand" Text="Previous"/> <RoutedUICommand x:Key="DeleteCustomerCommand" Text="Delete Customer"/> <RoutedUICommand x:Key="DeleteOrderCommand" Text="Delete Order"/> <RoutedUICommand x:Key="UpdateCommand" Text="Update"/> <RoutedUICommand x:Key="AddCommand" Text="Add"/> <RoutedUICommand x:Key="CancelCommand" Text="Cancel"/>Bir
CommandBindingolay, arkasındaki koddaki bir yönteme eşlerRoutedUICommand. BuCommandBindingsöğeyi kapanış etiketindenWindows.Resourcessonra aşağıdaki gibi ekleyin:<Window.CommandBindings> <CommandBinding Command="{StaticResource FirstCommand}" Executed="FirstCommandHandler"/> <CommandBinding Command="{StaticResource LastCommand}" Executed="LastCommandHandler"/> <CommandBinding Command="{StaticResource NextCommand}" Executed="NextCommandHandler"/> <CommandBinding Command="{StaticResource PreviousCommand}" Executed="PreviousCommandHandler"/> <CommandBinding Command="{StaticResource DeleteCustomerCommand}" Executed="DeleteCustomerCommandHandler"/> <CommandBinding Command="{StaticResource DeleteOrderCommand}" Executed="DeleteOrderCommandHandler"/> <CommandBinding Command="{StaticResource UpdateCommand}" Executed="UpdateCommandHandler"/> <CommandBinding Command="{StaticResource AddCommand}" Executed="AddCommandHandler"/> <CommandBinding Command="{StaticResource CancelCommand}" Executed="CancelCommandHandler"/> </Window.CommandBindings>StackPanelöğesini gezinti, ekleme, silme ve güncelleştirme düğmeleriyle ekleyin. Bu stiliWindows.Resourcesögesine ekleyin.<Style x:Key="NavButton" TargetType="{x:Type Button}" BasedOn="{x:Null}"> <Setter Property="FontSize" Value="24"/> <Setter Property="FontFamily" Value="Segoe UI Symbol"/> <Setter Property="Margin" Value="2,2,2,0"/> <Setter Property="Width" Value="40"/> <Setter Property="Height" Value="auto"/> </Style>Bu kodu, XAML sayfasının üst kısmındaki dış
RowDefinitionsöğesi içinGridöğesinin hemen arkasına yapıştırın.<StackPanel Orientation="Horizontal" Margin="2,2,2,0" Height="36" VerticalAlignment="Top" Background="Gainsboro" DataContext="{StaticResource customerViewSource}" d:LayoutOverrides="LeftMargin, RightMargin, TopMargin, BottomMargin"> <Button Name="btnFirst" Content="|◄" Command="{StaticResource FirstCommand}" Style="{StaticResource NavButton}"/> <Button Name="btnPrev" Content="◄" Command="{StaticResource PreviousCommand}" Style="{StaticResource NavButton}"/> <Button Name="btnNext" Content="►" Command="{StaticResource NextCommand}" Style="{StaticResource NavButton}"/> <Button Name="btnLast" Content="►|" Command="{StaticResource LastCommand}" Style="{StaticResource NavButton}"/> <Button Name="btnDelete" Content="Delete Customer" Command="{StaticResource DeleteCustomerCommand}" FontSize="11" Width="120" Style="{StaticResource NavButton}"/> <Button Name="btnAdd" Content="New Customer" Command="{StaticResource AddCommand}" FontSize="11" Width="80" Style="{StaticResource NavButton}"/> <Button Content="New Order" Name="btnNewOrder" FontSize="11" Width="80" Style="{StaticResource NavButton}" Click="NewOrder_click"/> <Button Name="btnUpdate" Content="Commit" Command="{StaticResource UpdateCommand}" FontSize="11" Width="80" Style="{StaticResource NavButton}"/> <Button Content="Cancel" Name="btnCancel" Command="{StaticResource CancelCommand}" FontSize="11" Width="80" Style="{StaticResource NavButton}"/> </StackPanel>
MainWindow sınıfına komut işleyicileri ekleme
MainWindow.xaml.cs içerisindeki arkakod, ekleme ve silme yöntemleri dışında minimaldir.
Gezinmek için
ViewnesnesininCollectionViewSourceözelliği üzerindeki yöntemleri çağırın.Bir siparişte kaskad silme işlemi gerçekleştirmek için, kod örneğinde gösterildiği gibi
DeleteOrderCommandHandleröğesini kullanın. Ancak, önce ilişkiliOrder_Detailssiparişi silmeniz gerekir.Koleksiyonuna
UpdateCommandHandlermüşteri veya sipariş eklemek ya da var olan bir müşteriyi veya siparişi kullanıcının metin kutularında yaptığı değişikliklerle güncelleştirmek için kullanın.Bu işleyici yöntemleri
MainWindowsınıfı içindeMainWindow.xaml.csekleyin.CollectionViewSourceMüşteriler tablosunun adı farklıysa, yöntemlerin her birinde adı ayarlamanız gerekir:private void LastCommandHandler(object sender, ExecutedRoutedEventArgs e) { custViewSource.View.MoveCurrentToLast(); } private void PreviousCommandHandler(object sender, ExecutedRoutedEventArgs e) { custViewSource.View.MoveCurrentToPrevious(); } private void NextCommandHandler(object sender, ExecutedRoutedEventArgs e) { custViewSource.View.MoveCurrentToNext(); } private void FirstCommandHandler(object sender, ExecutedRoutedEventArgs e) { custViewSource.View.MoveCurrentToFirst(); } private void DeleteCustomerCommandHandler(object sender, ExecutedRoutedEventArgs e) { // If existing window is visible, delete the customer and all their orders. // In a real application, you should add warnings and allow the user to cancel the operation. var cur = custViewSource.View.CurrentItem as Customer; var cust = (from c in context.Customers where c.CustomerID == cur.CustomerID select c).FirstOrDefault(); if (cust != null) { foreach (var ord in cust.Orders.ToList()) { Delete_Order(ord); } context.Customers.Remove(cust); } context.SaveChanges(); custViewSource.View.Refresh(); } // Commit changes from the new customer form, the new order form, // or edits made to the existing customer form. private void UpdateCommandHandler(object sender, ExecutedRoutedEventArgs e) { if (newCustomerGrid.IsVisible) { // Create a new object because the old one // is being tracked by EF now. Customer newCustomer = new Customer { Address = add_addressTextBox.Text, City = add_cityTextBox.Text, CompanyName = add_companyNameTextBox.Text, ContactName = add_contactNameTextBox.Text, ContactTitle = add_contactTitleTextBox.Text, Country = add_countryTextBox.Text, CustomerID = add_customerIDTextBox.Text, Fax = add_faxTextBox.Text, Phone = add_phoneTextBox.Text, PostalCode = add_postalCodeTextBox.Text, Region = add_regionTextBox.Text }; // Perform very basic validation if (newCustomer.CustomerID.Length == 5) { // Insert the new customer at correct position: int len = context.Customers.Local.Count(); int pos = len; for (int i = 0; i < len; ++i) { if (String.CompareOrdinal(newCustomer.CustomerID, context.Customers.Local[i].CustomerID) < 0) { pos = i; break; } } context.Customers.Local.Insert(pos, newCustomer); custViewSource.View.Refresh(); custViewSource.View.MoveCurrentTo(newCustomer); } else { MessageBox.Show("CustomerID must have 5 characters."); } newCustomerGrid.Visibility = Visibility.Collapsed; existingCustomerGrid.Visibility = Visibility.Visible; } else if (newOrderGrid.IsVisible) { // Order ID is auto-generated so we don't set it here. // For CustomerID, address, etc we use the values from current customer. // User can modify these in the datagrid after the order is entered. Customer currentCustomer = (Customer)custViewSource.View.CurrentItem; Order newOrder = new Order() { OrderDate = add_orderDatePicker.SelectedDate, RequiredDate = add_requiredDatePicker.SelectedDate, ShippedDate = add_shippedDatePicker.SelectedDate, CustomerID = currentCustomer.CustomerID, ShipAddress = currentCustomer.Address, ShipCity = currentCustomer.City, ShipCountry = currentCustomer.Country, ShipName = currentCustomer.CompanyName, ShipPostalCode = currentCustomer.PostalCode, ShipRegion = currentCustomer.Region }; try { newOrder.EmployeeID = Int32.Parse(add_employeeIDTextBox.Text); } catch { MessageBox.Show("EmployeeID must be a valid integer value."); return; } try { // Exercise for the reader if you are using Northwind: // Add the Northwind Shippers table to the model. // Acceptable ShipperID values are 1, 2, or 3. if (add_ShipViaTextBox.Text == "1" || add_ShipViaTextBox.Text == "2" || add_ShipViaTextBox.Text == "3") { newOrder.ShipVia = Convert.ToInt32(add_ShipViaTextBox.Text); } else { MessageBox.Show("Shipper ID must be 1, 2, or 3 in Northwind."); return; } } catch { MessageBox.Show("Ship Via must be convertible to int"); return; } try { newOrder.Freight = Convert.ToDecimal(add_freightTextBox.Text); } catch { MessageBox.Show("Freight must be convertible to decimal."); return; } // Add the order into the EF model context.Orders.Add(newOrder); ordViewSource.View.Refresh(); } // Save the changes, either for a new customer, a new order // or an edit to an existing customer or order. context.SaveChanges(); } // Sets up the form so that user can enter data. Data is later // saved when user clicks Commit. private void AddCommandHandler(object sender, ExecutedRoutedEventArgs e) { existingCustomerGrid.Visibility = Visibility.Collapsed; newOrderGrid.Visibility = Visibility.Collapsed; newCustomerGrid.Visibility = Visibility.Visible; // Clear all the text boxes before adding a new customer. foreach (var child in newCustomerGrid.Children) { var tb = child as TextBox; if (tb != null) { tb.Text = ""; } } } private void NewOrder_click(object sender, RoutedEventArgs e) { var cust = custViewSource.View.CurrentItem as Customer; if (cust == null) { MessageBox.Show("No customer selected."); return; } existingCustomerGrid.Visibility = Visibility.Collapsed; newCustomerGrid.Visibility = Visibility.Collapsed; newOrderGrid.UpdateLayout(); newOrderGrid.Visibility = Visibility.Visible; } // Cancels any input into the new customer form private void CancelCommandHandler(object sender, ExecutedRoutedEventArgs e) { add_addressTextBox.Text = ""; add_cityTextBox.Text = ""; add_companyNameTextBox.Text = ""; add_contactNameTextBox.Text = ""; add_contactTitleTextBox.Text = ""; add_countryTextBox.Text = ""; add_customerIDTextBox.Text = ""; add_faxTextBox.Text = ""; add_phoneTextBox.Text = ""; add_postalCodeTextBox.Text = ""; add_regionTextBox.Text = ""; existingCustomerGrid.Visibility = Visibility.Visible; newCustomerGrid.Visibility = Visibility.Collapsed; newOrderGrid.Visibility = Visibility.Collapsed; } private void Delete_Order(Order order) { // Find the order in the EF model. var ord = (from o in context.Orders.Local where o.OrderID == order.OrderID select o).FirstOrDefault(); // Delete all the order_details that have // this Order as a foreign key foreach (var detail in ord.Order_Details.ToList()) { context.Order_Details.Remove(detail); } // Now it's safe to delete the order. context.Orders.Remove(ord); context.SaveChanges(); // Update the data grid. ordViewSource.View.Refresh(); } private void DeleteOrderCommandHandler(object sender, ExecutedRoutedEventArgs e) { // Get the Order in the row in which the Delete button was clicked. Order obj = e.Parameter as Order; Delete_Order(obj); }
WPF uygulamasını çalıştırma
Hata ayıklamayı başlatmak için F5 tuşuna basın. Müşteri ve sipariş verilerinin kılavuzda doldurulduğunu ve gezinti düğmelerinin beklendiği gibi çalıştığını doğrulayın.
Verileri girdikten sonra modele yeni bir müşteri veya sipariş eklemek için İşle'yi seçin.
Verileri kaydetmeden yeni bir müşteriden veya yeni sipariş formundan çıkmak için İptal'i seçin.
Mevcut müşteri ve siparişlerde doğrudan düzenleme yapmak için, bu değişiklikleri modele otomatik olarak yazan metin kutularını kullanın.