2013-02-13 17 views
6

Użyłem WPF do opracowania dwóch umiarkowanie dużych aplikacji. Byłem pod wrażeniem czystości WPF i jej funkcji. Kiedy wyjaśnił jeden z moich współpracowników (który akurat do rozwijania aplikacji biznesowych) różne korzyści WPF, wyzwał mnie z tym problemem, który miał mi zupełnie zakłopotany:Jaka jest odpowiedź WPF na to?

Problem:

on zakodowany aplikacja w następujący sposób za około 2 minuty:

  1. Otwórz nowy projekt WinForms.
  2. Zdefiniuj klasę Loan.
  3. Projekt budowy.
  4. Definiowanie źródła danych obiektu za pomocą Loan.
  5. W Eksploratorze źródeł danych zmień typ widoku źródła danych Loan na Szczegóły.
  6. Przeciągnij źródło danych na formularz w projektancie.
  7. Dostarcz źródło danych do Loan[] zawierającego jeden obiekt.
  8. Utwórz i uruchom aplikację.

Kod:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace WinForms_DataBinding_Example 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     protected override void OnLoad(EventArgs e) 
     { 
      base.OnLoad(e); 

      loanBindingSource.DataSource = new Loan[] { new Loan() }; 
     } 
    } 

    public class Loan 
    { 
     public decimal Amount { get; set; } 
     public decimal Rate { get; set; } 
     public decimal Total { get { return Amount * Rate; } } 
    } 
} 

Projektant:

enter image description here

Aplikacja:

enter image description here

Teraz ilekroć zmieniasz wartość Amount lub Rate w oknie, wartość Total zmienia się odpowiednio. Po wyjaśnieniu, że jest to bardzo przydatna funkcja w aplikacjach biznesowych, w której wszelkie zmiany wprowadzane w jednej usłudze w jednostce natychmiast aktualizują widok, w którym obliczone właściwości są odświeżane natychmiast, poprawiając komfort użytkownika. Biorąc pod uwagę, że typowa klasa jednostek biznesowych ma wiele właściwości, oszczędza to wiele kodowania. Potem poprosił mnie, żebym zrobił to samo w WPF.

Najpierw wyjaśniłem mu, że nie rozumiem, jaka to czarna magia. W jaki sposób pole tekstowe Total aktualizuje się automatycznie? To jest moje pierwsze pytanie:

Q1. Klasa Loan nie implementuje INotifyPropertyChanged lub czegoś podobnego. Więc w jaki sposób pole tekstowe Total jest aktualizowane, gdy pola tekstowe tracą ostrość?

Potem powiedziałem mu, że nie wiem jak zrobić to samo tak łatwo w WPF. Jednak napisałem tę samą aplikację w WPF z 3 TextBlock s i 3 TextBox s w interfejsie użytkownika. Musiałem również wykonać klasę Loan implementacji urządzenia INotifyPropertyChanged. Dodano pola pomocnicze do Amount i Rate. Kiedykolwiek te właściwości były ustawiane, podniosłem powiadomienie o zmianie właściwości dla właściwości Total. W końcu zostałem z aplikacją ze źle wyrównanymi kontrolkami, które zrobiły to samo, co aplikacja WinForm.Jednak było to o wiele trudniejsze niż metoda WinForms.

Przyszedłem do domu, a następnie wpadłem na pomysł, by przeciągnąć źródło danych z Loan do okna WPF (Po zmianie trybu widoku na szczegóły). Oczywiście, mam ten sam rodzaj interfejsu jak w aplikacji WinForms i po ustawieniu źródła danych na ten sam Loan[] jak w aplikacji WinForms, wydawało się, że jest kompletny. Uruchomiłem aplikację, zmieniłem pola, mając nadzieję, że zmienią się automagicznie na Total. Jednak byłem rozczarowany. Pole Total nie uległa zmianie:

enter image description here

kodu:

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; 
using WinForms_DataBinding_Example; 

namespace WPF_Grid_Example 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     private void Window_Loaded_1(object sender, RoutedEventArgs e) 
     { 

      System.Windows.Data.CollectionViewSource loanViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("loanViewSource"))); 
      // Load data by setting the CollectionViewSource.Source property: 
      loanViewSource.Source = new List<Loan>() { new Loan() }; 
     } 
    } 
} 

XAML:

<Window 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:WinForms_DataBinding_Example="clr-namespace:WinForms_DataBinding_Example;assembly=WinForms_DataBinding_Example" mc:Ignorable="d" x:Class="WPF_Grid_Example.MainWindow" 
     Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded_1"> 
    <Window.Resources> 
     <CollectionViewSource x:Key="loanViewSource" d:DesignSource="{d:DesignInstance {x:Type WinForms_DataBinding_Example:Loan}, CreateList=True}"/> 
    </Window.Resources> 
    <Grid> 
     <Grid x:Name="grid1" DataContext="{StaticResource loanViewSource}" HorizontalAlignment="Left" Margin="121,123,0,0" VerticalAlignment="Top"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="Auto"/> 
       <ColumnDefinition Width="Auto"/> 
      </Grid.ColumnDefinitions> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
      </Grid.RowDefinitions> 
      <Label Content="Amount:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="0" VerticalAlignment="Center"/> 
      <TextBox x:Name="amountTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="0" Text="{Binding Amount, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/> 
      <Label Content="Rate:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="1" VerticalAlignment="Center"/> 
      <TextBox x:Name="rateTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="1" Text="{Binding Rate, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" VerticalAlignment="Center" Width="120"/> 
      <Label Content="Total:" Grid.Column="0" HorizontalAlignment="Left" Margin="3" Grid.Row="2" VerticalAlignment="Center"/> 
      <TextBox x:Name="totalTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="23" Margin="3" Grid.Row="2" Text="{Binding Total, Mode=OneWay}" VerticalAlignment="Center" Width="120"/> 
     </Grid> 

    </Grid> 
</Window> 

Q2. Byłem oszołomiony wcześniej przez czarną magię WinForms, byłem teraz zdezorientowany, ponieważ ta sama czarna magia nie działała w WPF. Czemu?

Q3. Jak sprawić, aby wersja WPF aktualizowała automatycznie pole Total, tak jak w przykładzie WinForm?

Q4. Która platforma jest lepsza/szybsza w przypadku tego rodzaju tworzenia aplikacji biznesowych? Jeśli mam przedstawić lepszy argument w imieniu WPF, na co powinienem zwrócić uwagę?

Mam nadzieję, że nie miałem wątpliwości co do tego problemu. Proszę dać mi znać, czy potrzebne są jakieś wyjaśnienia. Dzięki.

+3

wow .. Jestem pod wrażeniem, WinForm może automatycznie wygenerować ekran z 3 polami tekstowymi ... i co z tego? wszystko inne jest niemożliwe w WinForm, podczas gdy WPF daje możliwość dostosowania WSZYSTKIEGO i związania WSZYSTKIEGO z NIMI, nie tylko, powiedz właściwość Tekst, jak w winformach. PRAWDZIWY świat Aplikacje Line-of-Business to nie proste pola tekstowe, wymagają one dużo bardziej skomplikowanej logiki, a winFormy wymagają ogromnego kodu do wykonywania rzeczywistych aplikacji, w przeciwieństwie do prostych właściwości i XAML. –

+0

@HighCore: Jestem pewien, że masz rację. Ale twój komentarz nie odpowiada na żadne z moich pytań. :( – nakiya

+0

Ogólnie rzecz biorąc, wydaje mi się, że porównujesz dwa frameworki oparte na konkretnym przypadku użycia.Nie myślę, że prowadzi to do uczciwych wyników. – Ameen

Odpowiedz

5

Q1: Jeśli spojrzysz na plik projektanta dla formularza Windows, zobaczysz około 300 linii kodu wygenerowanych dla twoich 3 pól tekstowych. Część tego kodu jest podobny do:

this.amountTextBox.DataBindings.Add(
    new System.Windows.Forms.Binding("Text", 
     this.loanBindingSource, "Amount", true)); 

The Binding i BindingSource współpracują w celu aktualizacji wartości związanych i spowoduje, że wszystkie związane kontrole mają być aktualizowane za każdym razem jedna ze zmian wartości (przy użyciu odbicia).

Q2: Ponieważ projektant WPF nie tworzy pliku .Designer.cs i powiązanego z nim bałaganu kodu. Musisz jawnie zaimplementować INotifyPropertyChange, które można uprościć za pomocą ViewMVDMBel View MVVM Light, np.

public class Loan : ViewModelBase 
{ 
    public decimal Amount 
    { 
     get 
     { 
      return this.amount; 
     } 
     set 
     { 
      if (Set(() => Amount, ref this.amount, value)) 
      { 
       RaisePropertyChanged(() => Total); 
      } 
     } 
    } 

Q3: 1) W przypadku zmiany ilości lub Oceniaj podnieść powiadomienie o zmianie własność tej nieruchomości, ale także dla mienia komputerowej „ogółem”. 2) Zmodyfikuj wiązania na kwotę i stawkę na

Q4: WPF bez pytania (IMHO). Sposób WPF jest bardziej testowalny i obsługiwany i zrozumiały.

1

Odpowiedź na Q4:

Niezależnie od WinForms posiadających zdolność do generowania 3 głupie tekstowych do klasy, WPF jest znacznie lepiej, skalowalne i wydajne ramy. Ma znacznie większą wydajność ze względu na akceleracji sprzętowej i etażerka i wymaga mniej lub brak kodu zrobić kilka zadań, które mają mnóstwo kodu w WinForms, takich jak this, czy to:

<CheckBox x:Name="chk"/> 
<TextBox IsEnabled="{Binding IsChecked,ElementName=chk}"/> 

Również typowym liniowe z - Aplikacje biznesowe mają do czynienia z tysiącami lub setkami tysięcy rekordów i UI Virtualization makes a huge difference.

Najważniejsze jest to, że winFormy, niezależnie od tego, czy mają jakieś przysmaki dla projektantów (które są bardziej cechą Visual Studio niż same WinFormy), nie są tak praktyczne i adekwatne, jeśli chodzi o Line of Business.

Powiązane problemy