Pembuatan MVVM Application Menggunakan WPF

Nama: Reihan Nanda Ramadhan
NRP: 05111840000132
Kelas: PBKK - A

Halo semuanya! Bagaimana dengan tutorial sebelumnya, mudah diikuti bukan? Semoga saja mudah dan kalian bisa menerapkannya dan bahkan bisa membuat Money Converter yang lebih baik. Okay, sekarang aku ingin berbagi tutorial mengenai pembuatan MVVM (Model View View Model) Application menggunakan  WPF App atau Windows Presentation Foundation Application. Jadi aku akan membuat sebuah aplikasi sederhana yang mendata harga gitu. Nah, nanti aplikasi ini akan kusambungkan juga dengan MySQL sehingga datanya yang diinput bisa masuk ke dalam MySQL. Penasaran? Let's start the tutorial then!


1. Sebagai permulaan, aku akan membuat project baru. Di kolom search, aku akan mencari WPF App yang menggunakan .NET Framework, bukan yang .NET Core ya. Setelah selesai memilih WPF App (.NET Framework), tentukan nama file dan tempat penyimpanan lokal untuk file serta solution project nya. Lalu klik create!

Gambar 1. Project WPF App (.NET Framework)

"Rei, ini kok di VS2019 ku engga ada WPF App (.NET Framework)? Solusinya gimana?" Nah, kalau ternyata pas kalia cek project nya ternyata tidak ada template WPF App (.NET Framework) berarti kalian belum menginstall .NET Desktop Development plugin di Visual Studio 2019 Installer. Jadi pastikan kalian sudah menginstall plugin tersebut agar bisa menggunakan WPF App (.NET Framework) di VS2019.

Gambar 2. Plugin .NET Desktop Development di VS2019 Installer

2. Setelah project nya terbuat, langkah pertama yang harus kalian lakukan adalah membuat sebuah class baru bernama ItemPenjualan.cs. Untuk membuat class baru, kalian cukup menggunakan shortcut ctrl + shift + A atau bisa dengan klik kanan nama project kalian di solution explorer > add > new item.... Setelah masuk ke dalam menu add new item, kalian cukup memilih class C# lalu mengetikkan ItemPenjualan.cs dan create deh! Jadilah class baru yang siap kalian gunakan. Untuk ke depannya kita akan terus menggunakan cara ini untuk membuat sebuah class baru, jadi ingat terus ya caranya!


Gambar 3. Pembuatan class baru


3. Setelah class nya selesai dibuat, class tersebut akan kita isi dengan code di bawah ini. Kode nya sederhana kok dan kalian pasti cepat memahaminya. 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
 
namespace LatihanMVVM
{
    public class ItemPenjualan
    {
        public ItemPenjualan()
        {
            DiskonPersen = 0;
        }
 
        public long Id { get; set; }
 
        public string NamaBarang { get; set; }
 
        public int Jumlah { get; set; }
 
        public decimal Harga { get; set; }
 
        public decimal DiskonPersen { get; set; }
 
        public decimal Total()
        {
            decimal total = Jumlah * Harga;
            return total - (DiskonPersen / 100 * total);
        }
    }
}

Nah, ItemPenjualan.cs ini disebut dengan Model. Untuk isi dari ItemPenjualan.cs adalah operasi perhitungan dari aplikasi kita nanti, dimana terdapat diskon yang pada akhirnya mengubah total harga dari barang yang nanti diinput. 


4. Selanjutnya, aku akan mengubah interface atau view dari aplikasinya di MainWindow.xaml. Lho, kok .xaml? Nah, di WPF ini interface window nya menggunakan XAML , bukan HTML. XAML juga termasuk Markup Language seperti HTML. Okay, sekarang kalian cukup ganti kode program yang ada di MainWindow.xaml dengan kode di bawah ini.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<Window x:Class="LatihanMVVM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="356" Width="528">
 
    <Window.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="FontSize" Value="20" />
            <Setter Property="FontFamily" Value="Myriad Pro" />
            <Setter Property="FontWeight" Value="SemiBold" />
            <Setter Property="Background">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF508FC4" Offset="0" />
                        <GradientStop Color="#FF6F94AD" Offset="1" />
                        <GradientStop Color="#FFC7F3FF" Offset="0.302" />
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="Foreground">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF5252CE" Offset="0" />
                        <GradientStop Color="#FF0000DB" Offset="0.953" />
                        <GradientStop Color="#FF6363CB" Offset="0.337" />
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Style>
 
        <Style TargetType="Label">
            <Setter Property="FontSize" Value="14" />            
        </Style>
 
        <Style TargetType="TextBox">
            <Setter Property="Language" Value="in-IN" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Border x:Name="customBorder" Background="{TemplateBinding Background}" CornerRadius="5" BorderThickness="2" BorderBrush="Gray">
                            <ScrollViewer x:Name="PART_ContentHost"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsKeyboardFocused" Value="True">                                
                                <Setter TargetName="customBorder" Property="Effect">
                                    <Setter.Value>
                                        <DropShadowEffect BlurRadius="10" ShadowDepth="0" Color="#578EC9"/>
                                    </Setter.Value>
                                </Setter>                                
                            </Trigger>
                            <Trigger Property="IsKeyboardFocused" Value="False">
                                <Setter Property="Foreground" Value="Gray" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
 
        <Style TargetType="Button">
            <Setter Property="Background" Value="#DEF2FC" />
            <Setter Property="Foreground" Value="Black" />
            <Setter Property="FontSize" Value="15"/>
            <Setter Property="Effect">
                <Setter.Value>
                    <DropShadowEffect BlurRadius="10" ShadowDepth="0" Color="#578EC9"/>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border x:Name="customBorder" Background="{TemplateBinding Background}" CornerRadius="4" BorderThickness="2" BorderBrush="Gray">
                            <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" />
                        </Border>     
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" Value="#2394CC" />
                                <Setter Property="Foreground" Value="White" />                                
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">                                
                                <Setter Property="Effect" Value="{x:Null}" />
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="Effect">
                                    <Setter.Value>
                                        <BlurEffect Radius="3"  />
                                    </Setter.Value>
                                </Setter>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>                    
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
 
    <Grid>        
        <Label Content="Nama Barang:" Height="29" HorizontalAlignment="Left" Margin="0,49,0,0" Name="label2" VerticalAlignment="Top" HorizontalContentAlignment="Right" Width="107" />
        <TextBox Height="23" HorizontalAlignment="Stretch" Margin="112,55,12,0" Name="textBox1" VerticalAlignment="Top" />
        <Label Content="Jumlah:" Height="27" HorizontalAlignment="Left" Margin="1,86,0,0" Name="label3" VerticalAlignment="Top" Width="106" HorizontalContentAlignment="Right" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="113,90,0,0" Name="textBox2" VerticalAlignment="Top" Width="62" />
        <Label Content="Harga:" Height="28" HorizontalAlignment="Left" Margin="12,122,0,0" Name="label4" VerticalAlignment="Top" HorizontalContentAlignment="Right" Width="95" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="113,127,0,0" Name="textBox3" VerticalAlignment="Top" Width="124" />
        <Button Content="Simpan" Height="27" HorizontalAlignment="Left" Margin="207,228,0,0" Name="button1" VerticalAlignment="Top" Width="82" />
        <Label Content="Diskon (%):" Height="33" HorizontalAlignment="Left" Margin="12,161,0,0" Name="label5" VerticalAlignment="Top" HorizontalContentAlignment="Right" Width="95" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="113,165,0,0" Name="textBox4" VerticalAlignment="Top" Width="62" />
        <Label Content="Total:" Height="33" HorizontalAlignment="Left" Margin="12,194,0,0" Name="label6" VerticalAlignment="Top" HorizontalContentAlignment="Right" Width="95" />
        <Label Content="Label" Height="28" HorizontalAlignment="Left" Margin="113,194,0,0" Name="label7" VerticalAlignment="Top" Width="402" />
        <TextBlock Height="28" HorizontalAlignment="Stretch" Name="textBlock1" Text="Tambah Item Penjualan" VerticalAlignment="Top" TextAlignment="Center" Margin="0,12,0,0" />
 
        <Grid.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FFB7CEFF" Offset="0.192" />
                <GradientStop Color="White" Offset="1" />
                <GradientStop Color="#FF1648AD" Offset="0" />
            </LinearGradientBrush>
        </Grid.Background>
 
    </Grid>
</Window>

Setelah kalian terapkan kode di atas, tampilan interface nya akan menjadi seperti ini.

Gambar 4. Interface Window 

5. MVVM terdiri dari 3 komponen, kan? Model, View, dan View Model. Model dan View sudah kita atur, tinggal View Model yang tersisa. Sekarang aku cukup buat class baru dengan nama ItemPenjualanViewModel.cs. Selesai terbuat, isi file nya dengan kode di bawah ini.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
 
namespace LatihanMVVM
{
    class ItemPenjualanViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
 
        private ItemPenjualan model;
 
        public ItemPenjualanViewModel(ItemPenjualan itemPenjualan = null)
        {
            this.model = itemPenjualan ?? new ItemPenjualan();
        }
 
        public string NamaBarang
        {
            get { return model.NamaBarang; }
            set
            {
                if (value != model.NamaBarang)
                {
                    model.NamaBarang = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("NamaBarang"));
                }
            }
        }
 
        public int Jumlah
        {
            get { return model.Jumlah; }
            set
            {
                if (value != model.Jumlah)
                {
                    model.Jumlah = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("Jumlah"));
                    PropertyChanged(this, new PropertyChangedEventArgs("Total"));
                }
            }
        }
 
        public decimal Harga
        {
            get { return model.Harga; }
            set
            {
                if (value != model.Harga)
                {
                    model.Harga = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("Harga"));
                    PropertyChanged(this, new PropertyChangedEventArgs("Total"));
                }
            }
        }
 
        public decimal DiskonPersen
        {
            get { return model.DiskonPersen; }
            set
            {
                if (value != model.DiskonPersen)
                {
                    model.DiskonPersen = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("DiskonPersen"));
                    PropertyChanged(this, new PropertyChangedEventArgs("Total"));
                }
            }
        }
 
        public string Total
        {
            get
            {
                decimal? total = model.Total();
                if (!total.HasValue)
                {
                    return "-";
                }
                else
                {
                    return total.Value.ToString("C");
                }
            }
        }
 
        public ItemPenjualan Model
        {
            get { return this.model; }
        }
    }
}


6. Setelah membuat View Model, saatnya menggabungkan tiga komponen yang sudah kubuat. Caranya dengan mengedit kode yang ada di MainWindow.xaml.cs dengan kode di bawah ini.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
 using System.Windows.Documents;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Navigation;
 using System.Windows.Shapes;

 namespace Tutorial_MVVM
 {
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new ItemPenjualanViewModel();
        }
    }
 }


7. Oh iya, jangan lupa untuk melakukan Binding Attribute ke setiap atribut yang ada di dalam aplikasi kita agar data yang ada di view dapat diteruskan ke model. Tambahkan kode Binding di bawah ini ke file MainWindow.xaml.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
...
<Label Content="Nama Barang:" ... />
<TextBox Name="textBox1" ... Text="{Binding Path=NamaBarang}"/>
 
<Label Content="Jumlah:" ... />
<TextBox ... Text="{Binding Path=Jumlah, StringFormat={}{0:#,0}}"/>
 
<Label Content="Harga:" ... />
<TextBox ... Text="{Binding Path=Harga, StringFormat={}{0:C}}"/>                
 
<Label Content="Diskon (%):" ... />
<TextBox ... Text="{Binding Path=DiskonPersen, StringFormat={}{0:#.#}}"/>
 
<Label Content="Total:" ... />
<Label .... Content="{Binding Path=Total}" />
...


Gambar 5. Interface aplikasi setelah proses Binding


8. Setiap aplikasi pasti memiliki error handling kan? Nah aku ingin menambahkan error handling ke aplikasi ini dimana jika kolomnya dikosongkan atau isi kolomnya dicampur oleh special character, maka aplikasi akan memunculkan warning error. Kalian cukup tambahkan kode di bawah ini di MainWindow.xaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
...
<Style TargetType="TextBox">
   ...
   <Setter Property="Validation.ErrorTemplate">
      <Setter.Value>
         <ControlTemplate>
            <StackPanel Orientation="Horizontal">
               <AdornedElementPlaceholder />                                                            
               <TextBlock Text="Perlu diperbaiki!" Padding="3" Foreground="Red" />
            </StackPanel>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
   ...
</Style>
...


Gambar 6. Error Handling

9. Aplikasinya selesai deh! Eits, tapi aplikasi ini belum bisa sepenuhnya bekerja. Sekarang saatnya menghubungkan aplikasi ini dengan MySQL Database agar data yang dimasukkan nanti bisa terdata dengan sempurna. Kalian harus menyiapkan MySQL Connector/.NET dan Entity Framework. Link untuk mendownload MySQL Connector/.NET bisa kalian cek di bawah ini.

Link Download MySQL Connector/.NET

Untuk mendownload Entity Framework, kalian bisa mendownloadnya langsung di dalam VS2019. Buka tools > NuGet Package Manager > Package Manager Console. Setelah console nya terbuka, kalian cukup ketik command di bawah ini.

Install-Package EntityFramework -Version 6.4.4


Gambar 7. Proses download Entity Framework

Kalian tinggal enter lalu tunggu deh sampai selesai install. Jika sudah terinstall, MySQL Connector  harus ditambahkan ke reference project kita. Mungkin kalian bertanya-tanya kenapa Entity Framekwork tidak ditambahkan juga. Tenang saja, Entity Framekwork sudah secara otomatis masuk ke dalam prject kita karena kita sudah menginstallnya melalui NuGet. Okay, sekarang kita tambahkan MySQL Connector dalam project kita dengan cara klik project > Add Reference... > Assemblies > Extensions. Setelah itu kalian tinggal search MySql.Data.Entity for EF6 dengan versi 6.8.7.0. Setelah itu, berikan centang dan klik OK. 

Gambar 8. Menambahkan MySQL Connector/.NET ke References


Gambar 9. Entity Framework dan MySQL Connector sudah masuk references

10. Setelah MySQL Connector dan Entity Framework masuk ke dalam references, saatnya setting koneksi database dengan aplikasi di App.config. Sesuaikan connectionString nya dengan konfigurasi databse kalian dari username sampai uid nya. Berikut contoh App.config yang bisa kalian contoh.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
		<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
		<section name="entityFramework"
		  type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
		  requirePermission="false"/>
	</configSections>
	<startup> 
		<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
	</startup>
	<entityFramework>
		<providers>
			<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
		</providers>
	</entityFramework>
	<connectionStrings>
		<add name="LatihanContext" connectionString="server=localhost; database=database_mvvm; uid=root;" providerName="MySql.Data.MySqlClient"/>
	</connectionStrings>
</configuration>


11. Agar penomoran atribut Id di dalam database dilakukan secara otomatis (Auto Number), aku menambahkan kode ini di ItemPenjualan.cs.

...
using System.ComponentModel.DataAnnotations.Schema;
 
namespace Tutorial_MVVM
{
    public class ItemPenjualan
    {
 
        ...
 
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public long Id { get; set; }
 
        [StringLength(50)]
        public string NamaBarang { get; set; }
 
        ...
 
    }
}


12. Pada MySQL EF 6, table _migrationhistory menghasilkan kolom yg terlalu besar. Untuk menangani ini, kita harus mengganti ukuran kolom tersebut saat di generate dengan cara membuat sebuah class MyHistoryContext.cs yang berisi kode sebagai berikut.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Data.Entity.Migrations.History;
 using System.Data.Common;
 using System.Data.Entity;

 namespace Tutorial_MVVM
 {
    class MyHistoryContext : HistoryContext
    {
        public MyHistoryContext(DbConnection dbConnection, string defaultSchema)
            : base(dbConnection, defaultSchema)
        {
        }

        protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<HistoryRow>().Property(p => p.MigrationId).HasMaxLength(100).IsRequired();
            modelBuilder.Entity<HistoryRow>().Property(p => p.ContextKey).HasMaxLength(200).IsRequired();
        }
    }

    public class ModelConfiguration : DbConfiguration
    {
        public ModelConfiguration()
        {
            SetHistoryContext("MySql.Data.MySqlClient", (c, s) => new MyHistoryContext(c, s));
        }
    }
 }


13. Agar fungsi database berfungsi sempurna, kita tambahkan trigger button di ItemPenjualanViewModel.cs agar data terkirim ke database. Berikut adalah kode tambahan untuk membuat trigger button ini.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Input;
using System.Windows;
 
namespace Tutorial_MVVM
{
    public class ItemPenjualanViewModel : INotifyPropertyChanged
    {
    ...
 
        private ICommand simpanCommand;
 
        ...
 
        public ICommand SimpanCommand
        {
            get
            {
                if (this.simpanCommand == null)
                {
                    this.simpanCommand = new SimpanCommand(this);
                }
                return this.simpanCommand; 
            }
        }
 
    }
 
 
    public class SimpanCommand : ICommand
    {
 
        private ItemPenjualanViewModel viewModel;
 
        public SimpanCommand(ItemPenjualanViewModel viewModel)
        {
            this.viewModel = viewModel;
        }
 
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
 
        public bool CanExecute(object parameter)
        {
            return viewModel.Model.Total() > 0;
        }
 
        public void Execute(object parameter)
        {
            using (var db = new LatihanContext())
            {
                db.Database.Log = Console.Write;
                db.DaftarItemPenjualan.Add(viewModel.Model);
                db.SaveChanges();
        MessageBox.Show("Data berhasil disimpan ke database");
            }
        }
 
    }
}


15. Terakhir, lakukan Binding pada atribut button di MainWindow.xaml.

1
2
3
...
<Button Content="Simpan" ... Command="{Binding SimpanCommand}"/>
...


Selesai deh! Hasil akhirnya akan terlihat seperti ini.

Gambar 10. Interface Aplikasi Ketika Baru Dibuka

Disini terlihat bahwa tombol Simpan tidak bisa kita tekan sebelum semua kolom terisi. Apabila sudah terisi, interface akan terlihat seperti ini.

Gambar 11. Interface Ketika Sudah Mengisi Data

Setelah data yang terisi sudah benar, klik Simpan dan tunggu notifikasi bahwa data berhasil disimpan. Tampilan interfance ketika data yang kita masukkan sudah tersimpan akan terlihat seperti berikut ini.

Gambar 12. Tampilan Ketika Data Sudah Masuk ke Database

Untuk memastikan bahwa data benar-benar masuk ke database, aku akan tunjukkan database nya.

Gambar 13. Tabel di Database Item Penjualan

Wah, masuk! Berarti aplikasi kita berjalan dengan benar. Okay deh, itu saja yang bisa aku sampaikan. Oh ya, aku akan sematkan link database nya jadi kalian tinggal import saja ke MySQL biar kalian tidak perlu ribet-ribet buat tabel baru. See you on the next tutorial, guys! Peace out~

Link download Database Tutorial_MVVM

Source: Menerapkan MVVM Di Windows Presentation Foundation (WPF)



Comments

Popular Posts