Tugas 4
MVVW pada WPF
Langkah pembuatan aplikasi:
- Memilih project WPF dengan menggunakan .NET Framework versi 5
- Membuat class ItemPenjualan sebagai model
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); } } } - Tambahkan reference System.ComponentModel.DataAnnotations pada solution aplikasi
- Mengubah kode program pada MainWindow.xaml untuk membuat tampilan aplikasi
<Window ...
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.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>Membuat class itemPenjualanViewModel sebagai viewmodel
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; } } }}
Mengubah class MainWindow.xaml.cs untuk menghubungkan model dengan view
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 LatihanMVVM{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DataContext = new ItemPenjualanViewModel(); } }}
- Mengubah kode program pada MainWindow.xaml untuk melakukan binding dan menambahkan validation
...<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}" />...
...<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>...
- Sebelum mengubah kode program pada MainWindow.xaml, kita perlu mendownload MySQL Connector/.NET versi 6. Disini saya menggunakan versi 6.8.7
- Selanjutnya kita perlu menambahkan reference MySql.Data.Entity.EF6
- Tambahkan Nuget Package Entity Framework 6
- Mengubah kode program pada App.config
<?xml version="1.0" encoding="utf-8"?><configuration> ... <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=latihan; uid=steven; password=12345" providerName="MySql.Data.MySqlClient" /> </connectionStrings></configuration>
Mengubah kode program pada ItemPenjualan.cs untuk menambahkan sebuah atribut di model agar nilai property Id dihasilkan secara otomatis oleh database (melalui auto number)
...using System.ComponentModel.DataAnnotations.Schema; namespace LatihanMVVM{ public class ItemPenjualan { ... [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public long Id { get; set; } [StringLength(50)] public string NamaBarang { get; set; } ... }}
Membuat class LatihanContext
using System.Data.Entity; namespace LatihanMVVM{ class LatihanContext : DbContext { public DbSet<ItemPenjualan> DaftarItemPenjualan { get; set; } }}Membuat class MyHistoryContext
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data.Entity.Migrations.History;using System.Data.Common;using System.Data.Entity; namespace LatihanMVVM{ public 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)); } }}Mengubah kode program dari class ItemPenjualanViewModel untuk menambah class SimpanCommand dan propertynya pada ViewModel
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.ComponentModel;using System.Windows.Input;using System.Windows; namespace LatihanMVVM{ 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"); } } }}Mengubah kode program pada MainWindow.xaml untuk melakukan binding pada button simpan
...<Button Content="Simpan" ... Command="{Binding SimpanCommand}"/>...Tambahkan kode pada LatihanContext.cs
using System.Data.Entity; namespace LatihanMVVM{
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))] class LatihanContext : DbContext { public DbSet<ItemPenjualan> DaftarItemPenjualan { get; set; } }}Buat migration database dengan cara membuka package manager console, lalu ketikkan Enable-Migrations dan Add-Migration dengan package name initialMigrate database dengan mengetikkan Update-Database dan database kita akan otomatis ter-updateJalankan program
Hasil:






Comments
Post a Comment