【发布时间】:2017-09-14 06:29:17
【问题描述】:
我正在尝试为 WPF 中的钢琴键盘编写 XAML 控件,该控件响应来自外部 MIDI 键盘的 NoteOn 和 NoteOff MIDI 事件。我正在使用 Tom Lokovic 的 midi-dot-net 来引发由硬件触发的 NoteOn 和 NoteOff 事件,但我需要一种方法来让这些事件引发我的 XAML Key 类(派生自 WPF 按钮)的 NoteOn 和 NoteOff 事件。键的颜色应该在它打开时改变,并且事件应该是可订阅的,以便钢琴键盘控件的用户可以播放按键被按下的声音。
我可以通过将每个 Midi.InputDevice 传递给键盘上的每个键来做到这一点,这样每个人都可以订阅每个 InputDevice 的 NoteOn 和 NoteOff 事件,然后依次引发他们自己的 NoteOn 和 NoteOff 事件,但问题在于这是因为 PianoKeyboard 控件(一个 ItemsControl 包含 Keys)及其嵌套的 Key 控件都与 midi-dot-net 的实现紧密耦合。如果我必须这样做,我会这样做,但似乎在 WPF 中应该有更好的方法来执行此操作,将 midi-dot-net 的依赖移到调用堆栈中更高的位置。
我有太多代码无法在此处完整粘贴,但仍然可以阅读,因此这里是我用作 PianoKeyboard 的 ItemTemplate 的其中一个 DataTemplate 的示例。
<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 按钮,如何让它触发按钮而不将其耦合到按钮的派生类?
【问题讨论】:
标签: c# wpf xaml events command