在 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" 作为按键按下状态??