2011-02-27 8 views
13

का उपयोग करके अवलोकन में ईवेंट पर क्लिक करें। मैं कुछ सी # कोड को दोहराने की कोशिश कर रहा हूं जो Button.Click ईवेंट से IObservable बनाता है। मैं इस कोड को एफ # पर पोर्ट करना चाहता हूं।एक WPF बटन को कैसे परिवर्तित करें। आरएक्स और एफ #

यहाँ मूल सी # कोड है जो त्रुटियों के बिना संकलित है:

Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>(
            h => new RoutedEventHandler(h), 
            h => btn.Click += h, 
            h => btn.Click -= h)) 

यहाँ मेरी नाकाम रहने के एफ # में भी ऐसा ही करने का प्रयास है:

Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>(
      Func<EventHandler<RoutedEventArgs>, RoutedEventHandler>(fun h -> RoutedEventHandler(h)), 
      Action<RoutedEventHandler>(fun h -> btn.Click.AddHandler h), 
      Action<RoutedEventHandler>(fun h -> btn.Click.RemoveHandler h)) 

सब कुछ की दूसरी पंक्ति के अलावा खुश है बयान।

एफ # संकलक की शिकायत के बारे में fun h -> RoutedEventHandler(h) क्योंकि यह RoutedEventHandler निर्माता को पैरामीटर के रूप h सिवाय नहीं चाहता है।

वें दूसरी ओर सी # संकलक दोनों कोड नमूने (सी # और एफ #) h के प्रकार EventHandler<RoutedEventArgs> है में, दिलचस्प बात यह h => new RoutedEventHandler(h)

को स्वीकार करने में कोई समस्या नहीं लगता है।

मैं एफ # संकलक से त्रुटि संदेश आ रहा है:

त्रुटि 2 इस अभिव्यक्ति के लिए प्रकार obj उम्मीद थी -> RoutedEventArgs -> इकाई लेकिन यहाँ लिखें eventhandler

है RoutedEventHandler कि मैं PresentationCore के अंदर पाए के लिए हस्ताक्षर है:

public delegate void RoutedEventHandler(object sender, RoutedEventArgs e);

आप देख सकते हैं यह एक object और RoutedEventArgs पैरामीटर के रूप में ले करता है, तो एफ # संकलक वास्तव में सही है।

वहाँ कुछ जादू है कि सी # संकलक पर्दे के पीछे होता है यह काम है कि एफ # संकलक नहीं है या मैं बस यहाँ कुछ याद आ रही है बनाने के लिए है?

किसी भी तरह से, मैं कैसे एफ # में यह काम कर सकते हैं?

उत्तर

17

सबसे आसान तरीका है मैं के बारे में पता एक WPF Button.Click घटना के बाहर एक IObservable<_> बनाने के लिए यह कास्ट करने के लिए है: ...

open System 
open System.Windows.Controls 

let btn = new Button() 
let obsClick = btn.Click :> IObservable<_> 

जांच obsClick

val obsClick : IObservable<Windows.RoutedEventArgs> 

यह संभव है क्योंकि मानक .NET घटनाओं का F # प्रतिनिधित्व प्रकार (इस मामले में) IEvent<Windows.RoutedEventHandler,Windows.RoutedEventArgs> है। जैसा कि आप प्रलेखन से देख सकते हैं, IEvent implements IObservable। दूसरे शब्दों में, एफ # में प्रत्येक एकल घटना पहले से ही IObservable है।

6

योएल मुलर स्थान पर है तो बस रिकार्ड के लिए: सी # कोड का एक सीधा अनुवाद होगा

Observable.FromEvent(
    (fun h -> RoutedEventHandler(fun sender e -> h.Invoke(sender, e))), 
    (fun h -> b.Click.AddHandler h), 
    (fun h -> b.Click.RemoveHandler h) 
) 
+0

धन्यवाद, परावर्तक में सी # कोड को देखकर मुझे लगता है कि 'h' वास्तव में विस्तार किया जाता है बनाया 'एच।'को आमंत्रित करें', जिसे तब एक विधि समूह के रूप में माना जाता है जो '(एस, ई) => एच। इन्वोक (एस, ई)' का प्रतिनिधित्व करता है और इस प्रकार रूटेडएवेंट हैंडलर हस्ताक्षर को संतुष्ट करता है। एक बार यह स्पष्ट हो जाने पर, यह स्पष्ट है कि आप अपने सुझाए गए एफ # कार्यान्वयन के साथ पैसे पर सही हैं। मैं यह भी मानता हूं कि जोएल म्यूएलर द्वारा सुझाए गए कम वर्बोज़ रूपांतरण को तब तक प्राथमिकता दी जानी चाहिए जब तक कि आपको प्रेषक को सीधे पकड़ने की आवश्यकता न हो (उदा। Args.Source के माध्यम से नहीं), क्योंकि यह केवल रूटेडएवेंट आर्ट्स का IObservable लौटाता है। –

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