2008-10-01 14 views
8

विंडोज फॉर्म आपको घटक, गैर-दृश्य तत्व विकसित करने की अनुमति देता है जिनमें एक डिज़ाइनर हो सकता है। अंतर्निहित घटकों में पृष्ठभूमिवर्कर, टाइमर, और बहुत सी एडीओ .NET ऑब्जेक्ट्स शामिल हैं। जटिल ऑब्जेक्ट की आसान कॉन्फ़िगरेशन प्रदान करने का यह एक अच्छा तरीका है, और यह डिज़ाइनर-समर्थित डेटा बाध्यकारी को सक्षम बनाता है।WinForms घटकों के डब्ल्यूपीएफ समतुल्य क्या है?

मैं WPF देख रहा हूं, और ऐसा लगता है कि घटकों की कोई अवधारणा नहीं है। क्या मैं इसके बारे में सही हूँ? क्या घटकों (या किसी घटक की तरह कुछ) बनाने का कोई तरीका है जिसे मैंने याद किया है?

मैंने बॉब के जवाब को स्वीकार कर लिया है क्योंकि बहुत सारे शोध के बाद मुझे लगता है कि फैंसी एडॉर्नर्स शायद ऐसा करने का एकमात्र तरीका है।

उत्तर

5

बस अपने स्वयं के अवलोकनों से, ऐसा लगता है कि माइक्रोसॉफ्ट घटकों और इसी तरह की चीजों से दूर जाने की कोशिश कर रहा है जीयूआई में मुझे लगता है कि डब्ल्यूपीएफ एक्सएएमएल में सख्ती से जीयूआई चीजों को सीमित करने की कोशिश करता है। मुझे लगता है कि डेटा बाध्यकारी एकमात्र अपवाद होगा। मुझे पता है कि मैं कोड-पीछे या अलग-अलग वर्गों या असेंबली में अधिकतर सब कुछ रखने की कोशिश करता हूं।

संभवतः बिल्कुल वही जवाब नहीं जो आप चाहते थे, लेकिन यह मेरा $ 0.02 है।

1

अभी तक, मुझे लगता है कि एकमात्र दृष्टिकोण यह समझता है कि वर्ग का एक स्थिर संसाधन उदाहरण और एक्सएएमएल से इसे कॉन्फ़िगर करना है। यह काम करता है, लेकिन अगर यह WinForms डिजाइनर घटक ट्रे की तरह कुछ था तो यह अच्छा होगा।

1

आप संसाधन संसाधन के अंदर जो भी चाहें डाल सकते हैं, जिसमें कक्षाएं शामिल हैं जिनके पास कभी भी डब्लूपीएफ के साथ कोई संबंध नहीं है।

निम्नलिखित XAML स्ट्रिंग "हैलो" स्ट्रिंग को सीधे एक विंडो में जोड़ता है (वास्तविक स्ट्रिंग, स्ट्रिंग को दिखाता है जो नियंत्रण नहीं है), आप कुछ भी जगह रखने के लिए उसी विधि का उपयोग कर सकते हैं - जिसमें आप स्वयं को XAML फ़ाइल में लिखते हैं ।

<Window x:Class="MyApp.Window1" 
    xmlns:sys="clr-namespace:System;assembly=mscorlib" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    > 
<Window.Resources> 
    <sys:String x:Key="MyString">Hello</sys:String> 
</Window.Resources> 
</Window> 
1

मेरे पास एक ही प्रश्न है। घटक-जैसी तंत्र का लाभ यह है कि डिजाइनर इसे मिश्रण में जोड़ सकता है, इसे प्रोजेक्ट एडिटर के साथ डिज़ाइनर में कॉन्फ़िगर कर सकता है, और डेटा बाइंडिंग का उपयोग कर सकता है। नीचे दिए गए समाधान के बारे में आप क्या सोचते हैं? यह काम करता हैं।

public class TimerComponent : FrameworkElement 
{ 
    public Timer Timer { get; protected set; } 

    public TimerComponent() 
    { 
     if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) 
     { 
      Visibility = Visibility.Collapsed; 
      Timer = new Timer(OnTimerTick, null, Timeout.Infinite, Timeout.Infinite); 
     } 
    } 

    void OnTimerTick(object ignore) 
    { 
     Dispatcher.BeginInvoke(new Action(RaiseTickEvent)); 
    } 

    #region DueTime Dependency Property 

    public int DueTime 
    { 
     get { return (int)GetValue(DueTimeProperty); } 
     set { SetValue(DueTimeProperty, value); } 
    } 

    public static readonly DependencyProperty DueTimeProperty = 
     DependencyProperty.Register("DueTime", typeof(int), typeof(TimerComponent), new UIPropertyMetadata(new PropertyChangedCallback(OnDueTimeChanged))); 

    static void OnDueTimeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     var target = obj as TimerComponent; 
     if (target.Timer != null) 
     { 
      var newDueTime = (int)e.NewValue; 
      target.Timer.Change(newDueTime, target.Period); 
     } 
    } 

    #endregion 

    #region Period Dependency Property 

    public int Period 
    { 
     get { return (int)GetValue(PeriodProperty); } 
     set { SetValue(PeriodProperty, value); } 
    } 

    public static readonly DependencyProperty PeriodProperty = 
     DependencyProperty.Register("Period", typeof(int), typeof(TimerComponent), new UIPropertyMetadata(new PropertyChangedCallback(OnPeriodChanged))); 

    static void OnPeriodChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     var target = obj as TimerComponent; 
     if (target.Timer != null) 
     { 
      var newPeriod = (int)e.NewValue; 
      target.Timer.Change(target.DueTime, newPeriod); 
     } 
    } 

    #endregion 

    #region Tick Routed Event 

    public static readonly RoutedEvent TickEvent = EventManager.RegisterRoutedEvent(
     "Tick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TimerComponent)); 

    public event RoutedEventHandler Tick 
    { 
     add { AddHandler(TickEvent, value); } 
     remove { RemoveHandler(TickEvent, value); } 
    } 

    private void RaiseTickEvent() 
    { 
     RoutedEventArgs newEventArgs = new RoutedEventArgs(TimerComponent.TickEvent); 
     RaiseEvent(newEventArgs); 
    } 

    #endregion 
} 

और निम्नानुसार उपयोग किया जाता है।

<StackPanel> 
    <lib:TimerComponent Period="{Binding ElementName=textBox1, Path=Text}" Tick="OnTimerTick" /> 
    <TextBox x:Name="textBox1" Text="1000" /> 
    <Label x:Name="label1" /> 
</StackPanel> 
संबंधित मुद्दे