2016-09-01 7 views
3

this C# codeを翻訳しようとしています。私の試みは、これまで:Fのカスタムルーティングイベント

type MyButtonSimple() as self = 
    inherit Button() 

    static let TapEvent = 
     EventManager.RegisterRoutedEvent 
      ("Tap", RoutingStrategy.Bubble, 
       typeof<RoutedEventHandler>, typeof<MyButtonSimple>) 

    let tapEvent = new Event<RoutedEventHandler, RoutedEventArgs>() 
    let raiseTapEvent() = 
     let newEventArgs = new RoutedEventArgs(TapEvent) 
     tapEvent.Trigger(self, newEventArgs) 

    [<CLIEvent>] 
    member x.Tap = tapEvent.Publish 

    // For demonstration purposes we raise the event when clicked 
    override self.OnClick() = 
     raiseTapEvent() 

MainWindow.xaml

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:funk="clr-namespace:funk;assembly=appWPF" 
    Title="Routed" Height="300" Width="400"> 
    <StackPanel Background="LightGray"> 
     <funk:MyButtonSimple Content="Spin" Background="#808080" Foreground="LightGray"> 
      <funk:MyButtonSimple.RenderTransform> 
       <TransformGroup> 
        <RotateTransform x:Name="rotate"/> 
       </TransformGroup> 
      </funk:MyButtonSimple.RenderTransform> 
      <funk:MyButtonSimple.Triggers> 
       <EventTrigger RoutedEvent="funk:MyButtonSimple.Tap"> 
        <BeginStoryboard> 
         <Storyboard RepeatBehavior="Forever"> 
          <DoubleAnimation 
           Storyboard.TargetName="rotate" 
           Storyboard.TargetProperty="Angle" 
           From="0" To="90" Duration="0:0:2"/> 
         </Storyboard> 
        </BeginStoryboard> 
       </EventTrigger> 
      </funk:MyButtonSimple.Triggers> 
     </funk:MyButtonSimple> 
    </StackPanel> 
</Window> 

がボタンをクリックすると、アニメーションを開始しません。

コードをRoutedEvent="funk:MyButtonSimple.Tap"からRoutedEvent="GotFocus"に変更すると、(Button.Clickがオーバーライドされた)動作例が得られます。

私が間違っていることは何ですか?

+0

''と書いてみましたか? –

+0

@Filippoはい、どちらもうまくいきません。 FrameworkElementまたはUIElementから継承されないイベントを指定する必要があります。 Button.Click。 – Funk

+2

'static member'を' static let'で置き換えてみてください。 –

答えて

3

これはF#で標準ではないかなりのことをしているので、これは難しいです。ここ

type MyButtonSimple() as self = 
    inherit Button() 

    static let tapEvent = 
     EventManager.RegisterRoutedEvent 
      ("Tap", RoutingStrategy.Bubble, 
       typeof<RoutedEventHandler>, typeof<MyButtonSimple>) 

    // Create a custom event so you can override AddHandler/RemoveHandler behavior 
    let tapEvent = 
     { new IDelegateEvent<RoutedEventHandler> with 
      member this.AddHandler del = self.AddHandler(MyButtonSimple.TapEvent, del) 
      member this.RemoveHandler del = self.RemoveHandler(MyButtonSimple.TapEvent, del) } 

    // Raise via routed eventing strategy 
    let raiseTapEvent() = 
     let newEventArgs = new RoutedEventArgs(MyButtonSimple.TapEvent) 
     self.RaiseEvent newEventArgs 

    // This isn't exactly the same, but public static fields aren't allowed in F#, and 
    // this works for WPF 
    static member TapEvent with get() = tapEvent 

    [<CLIEvent>] 
    member x.Tap = tapEvent 

    // For demonstration purposes we raise the event when clicked 
    override self.OnClick() = 
     raiseTapEvent() 

メイン「落とし穴」あなたは自分自身をIDelegateEventを実装する代わりに、通常のF#のイベント管理を使用する必要があり、標準のイベント動作をオーバーライドする必要があるということです。

そのC#コードの変換は次のようになります。また、F#でpublic static readonlyフィールドを実行することはできません。これにより、イベントがプロパティにラップされます。ルーテッドイベントを実装するための「標準的な」方法ではないにしても、WPFはこれでうまくいくようです。

+0

賢明な回避策!感謝します、ありがとう。 – Funk