2013-02-13 15 views
6

मैंने दो मध्यम आकार के अनुप्रयोगों को विकसित करने के लिए डब्ल्यूपीएफ का उपयोग किया है। मैं डब्ल्यूपीएफ और इसकी सुविधाओं की शुद्धता से बहुत प्रभावित था।इसका डब्ल्यूपीएफ जवाब क्या है?

समस्या::

वह एक कोडित जब मैं अपने सहयोगियों WPF के विभिन्न लाभ (कौन व्यवसाय एप्लिकेशन विकसित करने के लिए होता है) से एक के लिए बताया गया है, वह मुझे इस समस्या को जो था मुझे पूरी तरह से स्टम्प्ड साथ चुनौती दी लगभग 2 मिनट में निम्न तरीके से आवेदन:

  1. एक नया WinForms प्रोजेक्ट खोलें।
  2. कक्षा Loan परिभाषित करें।
  3. प्रोजेक्ट बनाएं।
  4. Loan का उपयोग कर किसी ऑब्जेक्ट डेटा स्रोत को परिभाषित करें।
  5. डेटा स्रोत एक्सप्लोरर में, विवरण के Loan डेटा स्रोत के दृश्य प्रकार को बदलें।
  6. डेटा स्रोत को डिज़ाइनर में फ़ॉर्म पर खींचें।
  7. एक ऑब्जेक्ट युक्त Loan[] के साथ डेटा स्रोत की आपूर्ति करें।
  8. एप्लिकेशन बनाएं और चलाएं।

कोड:

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; } } 
    } 
} 

डिजाइनर:

enter image description here

आवेदन:

enter image description here

अब जब भी आप खिड़की में Amount या Rate के मान को बदलते हैं, Total का मान तदनुसार बदलता है। यह समझाने के बाद कि यह व्यावसायिक ऐप्स में एक बहुत ही उपयोगी विशेषता है, जहां आप किसी इकाई में किसी संपत्ति में किए गए किसी भी बदलाव को तुरंत उस दृश्य को अपडेट करते हैं जहां गणना की गई संपत्ति तुरंत उपयोगकर्ता अनुभव को बेहतर तरीके से रीफ्रेश कर दी जाती है। इस बात पर विचार करते हुए कि ठेठ व्यावसायिक इकाई वर्ग में बहुत सारी संपत्तियां हैं, इससे बहुत सारी कोडिंग बचाती है। फिर उसने मुझे डब्ल्यूपीएफ में ऐसा करने के लिए कहा।

मैंने पहली बार उसे समझाया कि मुझे समझ में नहीं आता कि यहां किस प्रकार का काला जादू चल रहा है। Total टेक्स्टबॉक्स स्वचालित रूप से अपडेट कैसे होता है? यह मेरा पहला सवाल है:

प्रश्न 1। Loan कक्षा INotifyPropertyChanged या कुछ इसी तरह लागू नहीं करती है। तो Total टेक्स्टबॉक्स अपडेट कैसे होता है जब Amount या Rate टेक्स्टबॉक्स फोकस खो देते हैं?

तब मैंने उनसे कहा कि मुझे नहीं पता कि डब्ल्यूपीएफ में इतनी आसानी से कैसे करना है। हालांकि, मैंने यूपी में 3 TextBlock एस और 3 TextBox एस के साथ डब्ल्यूपीएफ में एक ही ऐप लिखा था। मुझे Loan वर्ग INotifyPropertyChanged लागू करने की भी आवश्यकता है। Amount और Rate पर बैकिंग फ़ील्ड जोड़ा गया। जब भी ये गुण सेट किए जा रहे थे, मैंने संपत्ति Total संपत्ति के लिए अधिसूचना बदल दी। अंत में, मुझे एक ऐप के साथ बुरी तरह गठबंधन नियंत्रण के साथ छोड़ दिया गया था जो WinForms ऐप के समान ही था।हालांकि, WinForms विधि से ऐसा करना कठिन था।

मैं घर आया और उसके बाद WPF विंडो पर Loan डेटा स्रोत ड्रैग-ड्रॉप करने का उज्ज्वल विचार था (जब मैंने व्यू मोड को विस्तार से बदल दिया)। निश्चित रूप से, मुझे WinForms ऐप में एक ही तरह का यूआई मिला और WinForms ऐप में डेटा स्रोत को उसी Loan[] पर सेट करने के बाद, यह पूरा होना प्रतीत होता था। मैंने ऐप चलाया, Amount और Rate फ़ील्ड को Total स्वचालित रूप से बदलने की उम्मीद कर रहे फ़ील्ड को बदल दिया। हालांकि, मैं निराश था। Total क्षेत्र परिवर्तन नहीं किया:

enter image description here

कोड:

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 में काम नहीं किया था। क्यूं कर?

क्यू 3। मैं WinForms उदाहरण में स्वचालित रूप से Total फ़ील्ड को अपडेट करने के लिए WPF संस्करण कैसे बना सकता हूं?

क्यू 4। इस तरह के व्यावसायिक ऐप विकास के लिए कौन सा मंच बेहतर/तेज है? अगर मैं डब्ल्यूपीएफ की ओर से बेहतर तर्क देना चाहता हूं, तो मुझे क्या देखना चाहिए?

मुझे आशा है कि मैं समस्या के बारे में स्पष्ट था। यदि कोई स्पष्टीकरण की आवश्यकता है तो कृपया मुझे बताएं। धन्यवाद।

+3

वाह .. मुझे प्रभावित है, Winforms 3 टेक्स्टबॉक्स के साथ एक स्क्रीन उत्पन्न कर सकते हैं ... तो क्या? Winforms में कुछ भी असंभव है, जबकि डब्ल्यूपीएफ आपको सब कुछ अनुकूलित करने की क्षमता देता है, और कुछ भी नहीं, केवल टेक्स्ट प्रॉपर्टी को विनफॉर्म के रूप में कहता है। वास्तविक दुनिया लाइन-ऑफ-बिजनेस एप्लिकेशन सरल टेक्स्टबॉक्स नहीं हैं, उन्हें उससे अधिक जटिल तर्क की आवश्यकता होती है, और Winforms को सरल गुणों और एक्सएएमएल के खिलाफ असली एप्लिकेशन करने के लिए कोड का नरक की आवश्यकता होती है। –

+0

@ हाईकोर: मुझे यकीन है कि आप सही हैं। लेकिन आपकी टिप्पणी मेरे किसी भी प्रश्न का उत्तर नहीं देती है। :( – nakiya

+0

आम तौर पर, ऐसा लगता है कि आप एक विशिष्ट उपयोग मामले के आधार पर दो ढांचे की तुलना कर रहे हैं। मुझे नहीं लगता कि उचित परिणाम होते हैं। – Ameen

उत्तर

5

प्रश्न 1: यदि आप विंडोज फॉर्म के लिए डिज़ाइनर फ़ाइल देखते हैं तो आपको अपने 3 टेक्स्टबॉक्स के लिए जेनरेट की गई कोड की 300 लाइनें दिखाई देगी। इस कोड में से कुछ के समान है:

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

बाध्यकारी और BindingSource बाध्य मूल्यों को अद्यतन करने और (प्रतिबिंब का उपयोग) सभी के लिए बाध्य नियंत्रण हर बार मूल्यों परिवर्तनों में से एक अद्यतन करने की पैदा करने के लिए सहयोग।

प्रश्न 2: क्योंकि डब्ल्यूपीएफ डिजाइनर एक .esignign.cs फ़ाइल और कोड की संबंधित गड़बड़ी नहीं बनाता है। आपको INotifyPropertyChange को स्पष्ट रूप से कार्यान्वित करने की आवश्यकता है, जिसे एमवीवीएम लाइट के व्यू मॉडेलबेस का उपयोग करके सरलीकृत किया जा सकता है, उदा।

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

Q3: 1) राशि या दर परिवर्तन है कि संपत्ति के लिए, लेकिन यह भी गणना संपत्ति 'कुल' के लिए संपत्ति परिवर्तन सूचना जुटाने है। 2) अपनी बाइंडिंग्स को

Q4: WPF कोई प्रश्न (IMHO) पर संशोधित करें। डब्ल्यूपीएफ रास्ता अधिक टेस्टेबल और रखरखाव और समझने योग्य है।

1

Q4 के लिए उत्तर:

एक वर्ग के लिए 3 मूर्खतापूर्ण बक्सें उत्पन्न करने की क्षमता होने के बावजूद WinForms, WPF एक बेहतर, स्केलेबल और शक्तिशाली रूपरेखा है। यह हार्डवेयर त्वरण और whatnot की वजह से बहुत अधिक से अधिक प्रदर्शन किया है, और कम या कुछ कार्यों कि WinForms में कोड की टन ले करने के लिए कोई कोड जैसे this की आवश्यकता है, या इस:

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

इसके अलावा, tipical रेखा के- - व्यवसाय अनुप्रयोगों को हजारों या सैकड़ों हजारों रिकॉर्ड, और UI Virtualization makes a huge difference से निपटना होगा।

लब्बोलुआब यह है कि WinForms, कुछ डिजाइनर उपहार (जो और अधिक खुद WinForms से दृश्य स्टूडियो की एक विशेषता है) होने की परवाह किए बिना, कहीं नहीं के पास व्यावहारिक और पर्याप्त रूप में जब यह व्यापार की लाइन के लिए आता है।

संबंधित मुद्दे