私は WPF を使用して、適度なサイズのアプリケーションを 2 つ開発しました。WPF のクリーンさとその機能に感銘を受けました。同僚の 1 人 (たまたまビジネス アプリを開発している) に WPF のさまざまな利点を説明したとき、彼は次の問題について私に挑戦し、私は完全に困惑しました。
問題:
彼は、約 2 分で次のようにアプリケーションをコーディングしました。
- 新しい WinForms プロジェクトを開きます。
- クラスを定義し
Loan
ます。 - プロジェクトをビルドします。
- を使用してオブジェクト データ ソースを定義します
Loan
。 - データ ソース エクスプローラーで、
Loan
データ ソースのビュー タイプを [詳細] に変更します。 - データ ソースをデザイナーのフォームにドラッグします。
Loan[]
1 つのオブジェクトを含むデータ ソースを提供します。- アプリケーションをビルドして実行します。
コード:
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; } }
}
}
デザイナー:
アプリケーション:
ウィンドウ内でAmount
またはの値を変更すると、それに応じて の値も変更されます。これはビジネス アプリで非常に便利な機能であることを説明した後、エンティティ内の 1 つのプロパティに変更を加えるとすぐにビューが更新され、計算されたプロパティが即座に更新され、ユーザー エクスペリエンスが向上します。典型的なビジネス エンティティ クラスには多くのプロパティがあることを考えると、これにより多くのコーディングを節約できます。それから彼は私にWPFで同じことをするように頼んだ。Rate
Total
私は最初に、ここでどんな種類の黒魔術が行われているのかわからないことを彼に説明しました. テキストボックスはどのようにTotal
自動的に更新されますか? これは私の最初の質問です:
Q1. クラスは実装されLoan
ていませんINotifyPropertyChanged
。では、またはテキストボックスがフォーカスを失ったとき、テキストボックスはどのようTotal
に更新されるのでしょうか?Amount
Rate
それから私は、WPF で同じことを簡単に行う方法がわからないことを彼に伝えました。ただし、 UIで 3TextBlock
秒と 3秒の同じアプリを WPF で作成しました。また、クラスを実装TextBox
する必要がありました。とにバッキング フィールドを追加しました。これらのプロパティが設定されているときはいつでも、プロパティのプロパティ変更通知を発生させました。最終的に、WinForms アプリと同じことを行うコントロールが適切に配置されていないアプリが残っていました。ただし、これは WinForms メソッドよりもはるかに困難でした。Loan
INotifyPropertyChanged
Amount
Rate
Total
家に帰ってから、Loan
データソースをWPFウィンドウにドラッグアンドドロップするという素晴らしいアイデアを思いつきました(表示モードを詳細に変更した後)。案の定、WinForms アプリと同じ種類の UI が得られ、データ ソースをLoan[]
WinForms アプリと同じに設定したら、完成したように見えました。私はアプリを実行し、自動的に変更されることを期待してAmount
とRate
フィールドを変更しました。Total
しかし、私はがっかりしました。Total
フィールドは変更されませんでした:
コード:
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. 以前は WinForms のブラック マジックに戸惑いましたが、WPF では同じブラック マジックが機能しないため、今は困惑しています。なんで?
Q3. Total
WinForms の例のように、フィールドを自動的に更新するように WPF バージョンを作成するにはどうすればよいですか?
Q4. この種のビジネスアプリの開発には、どのプラットフォームが優れている/高速ですか? WPF に代わってより良い議論をする場合、何を見ればよいでしょうか?
問題が明確だったことを願っています。説明が必要な場合はお知らせください。ありがとう。