gpt4 book ai didi

wpf - F# 中的自定义路由事件

转载 作者:行者123 更新时间:2023-12-01 16:49:32 25 4
gpt4 key购买 nike

我正在尝试翻译 this C# code 。到目前为止我的尝试:

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>

单击按钮不会启动动画。

将代码 RoulatedEvent="funk:MyButtonSimple.Tap" 更改为 RoulatedEvent="GotFocus" 给出了一个工作示例(Button.Click 被覆盖)。

知道我做错了什么吗?

最佳答案

这很棘手,因为它做了很多 F# 中不标准的事情。

该 C# 代码的翻译如下:

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# 事件管理。此外,您无法在 F# 中执行公共(public)静态只读字段,因此这会将事件包装到属性中。 WPF 似乎对此很满意,尽管它不是实现路由事件的“标准”方式。

关于wpf - F# 中的自定义路由事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39276618/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com