在 XAML 中的控件上引发事件
Raising an event on a control in XAML
我正在尝试在 WPF 中为钢琴键盘编写一个 XAML 控件,它响应来自外部 MIDI 键盘的 NoteOn 和 NoteOff MIDI 事件。我正在使用 Tom Lokovic 的 midi-dot-net 引发由硬件触发的 NoteOn 和 NoteOff 事件,但我需要一种方法来获取这些事件以引发我的 XAML Key class 的 NoteOn 和 NoteOff 事件(派生自 WPF 按钮)。键的颜色在打开时应该改变,并且事件应该是可订阅的,以便钢琴键盘控件的用户可以在按下键时播放声音。
我可以通过将每个 Midi.InputDevice 传递给键盘上的每个键来做到这一点,这样每个键都可以订阅每个 InputDevice 的 NoteOn 和 NoteOff 事件,然后依次引发他们自己的 NoteOn 和 NoteOff 事件但问题在于 PianoKeyboard 控件(一个包含键的 ItemsControl)及其嵌套的键控件都与 midi-dot-net 的实现紧密耦合。如果我必须这样做,我会这样做,但在 WPF 中似乎应该有更好的方法来将对 midi-dot-net 的依赖移动到调用堆栈中更高的位置。
我有太多代码无法完整地粘贴到这里并且仍然可读,所以这里是我用作 PianoKeyboard 的 ItemTemplate 的数据模板之一的示例。
<DataTemplate x:Key="naturalKeyTemplate">
<!--NOTE: Background and Foreground Color assignment and changing is accounted for in the style.-->
<local:Key Grid.Column="{Binding Converter={StaticResource keyToColumnNumberConverter}}"
Grid.ColumnSpan="{Binding Converter={StaticResource keyToColumnSpanConverter}}"
Grid.RowSpan="2"
Style="{StaticResource naturalKeyStyle}"
Note="{Binding Note}"
IsHighlighted="{Binding IsHighlighted}">
<!--TODO: Find a way of raising the Key's NoteOn and NoteOff events from here.-->
</local:Key>
</DataTemplate>
基本上我要问的是:如果不支持输入设备触发具有按钮内置行为(例如鼠标单击)的 WPF 按钮,如何在不耦合的情况下触发按钮到按钮的派生 class?
您可以通过编程方式引发 Click
事件:
button1.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
我认为这可以帮助您根据调用的事件调用特定的方法。
<local:Key>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Mouse.PreviewMouseDown">
<ei:CallMethodAction MethodName="NoteOn"
TargetObject="{Binding}" />
</i:EventTrigger>
<i:EventTrigger EventName="Mouse.PreviewMouseUp">
<ei:CallMethodAction MethodName="NoteOff"
TargetObject="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</local:Key>
您将需要添加 xmlns 扩展:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
我会做一个 MIDI 侦听器服务单例来侦听所有 MIDI 事件,更新键盘状态存储库,公开绑定到键盘控件的视图模型......但我真的看不到你的程序结构,所以不好说。
将 xaml 中的 midi 事件绑定到包装器 midi.net 似乎不是 LOB 方式,因为你 link 带有 midi.net 的 gui。 .
顺便说一下,On/Off,这还不够,你需要 "pressed" 作为按键按下状态??
我正在尝试在 WPF 中为钢琴键盘编写一个 XAML 控件,它响应来自外部 MIDI 键盘的 NoteOn 和 NoteOff MIDI 事件。我正在使用 Tom Lokovic 的 midi-dot-net 引发由硬件触发的 NoteOn 和 NoteOff 事件,但我需要一种方法来获取这些事件以引发我的 XAML Key class 的 NoteOn 和 NoteOff 事件(派生自 WPF 按钮)。键的颜色在打开时应该改变,并且事件应该是可订阅的,以便钢琴键盘控件的用户可以在按下键时播放声音。
我可以通过将每个 Midi.InputDevice 传递给键盘上的每个键来做到这一点,这样每个键都可以订阅每个 InputDevice 的 NoteOn 和 NoteOff 事件,然后依次引发他们自己的 NoteOn 和 NoteOff 事件但问题在于 PianoKeyboard 控件(一个包含键的 ItemsControl)及其嵌套的键控件都与 midi-dot-net 的实现紧密耦合。如果我必须这样做,我会这样做,但在 WPF 中似乎应该有更好的方法来将对 midi-dot-net 的依赖移动到调用堆栈中更高的位置。
我有太多代码无法完整地粘贴到这里并且仍然可读,所以这里是我用作 PianoKeyboard 的 ItemTemplate 的数据模板之一的示例。
<DataTemplate x:Key="naturalKeyTemplate">
<!--NOTE: Background and Foreground Color assignment and changing is accounted for in the style.-->
<local:Key Grid.Column="{Binding Converter={StaticResource keyToColumnNumberConverter}}"
Grid.ColumnSpan="{Binding Converter={StaticResource keyToColumnSpanConverter}}"
Grid.RowSpan="2"
Style="{StaticResource naturalKeyStyle}"
Note="{Binding Note}"
IsHighlighted="{Binding IsHighlighted}">
<!--TODO: Find a way of raising the Key's NoteOn and NoteOff events from here.-->
</local:Key>
</DataTemplate>
基本上我要问的是:如果不支持输入设备触发具有按钮内置行为(例如鼠标单击)的 WPF 按钮,如何在不耦合的情况下触发按钮到按钮的派生 class?
您可以通过编程方式引发 Click
事件:
button1.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
我认为这可以帮助您根据调用的事件调用特定的方法。
<local:Key>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Mouse.PreviewMouseDown">
<ei:CallMethodAction MethodName="NoteOn"
TargetObject="{Binding}" />
</i:EventTrigger>
<i:EventTrigger EventName="Mouse.PreviewMouseUp">
<ei:CallMethodAction MethodName="NoteOff"
TargetObject="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</local:Key>
您将需要添加 xmlns 扩展:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
我会做一个 MIDI 侦听器服务单例来侦听所有 MIDI 事件,更新键盘状态存储库,公开绑定到键盘控件的视图模型......但我真的看不到你的程序结构,所以不好说。
将 xaml 中的 midi 事件绑定到包装器 midi.net 似乎不是 LOB 方式,因为你 link 带有 midi.net 的 gui。 .
顺便说一下,On/Off,这还不够,你需要 "pressed" 作为按键按下状态??