我正在尝试为WPF中的钢琴键盘编写一个XAML控件,它响应来自外部MIDI键盘的NoteOn和NoteOff MIDI事件。我正在使用Tom Lokovic的midi-dot-net来引发由硬件触发的NoteOn和NoteOff事件,但是我需要一种方法来获取这些事件来提升我的XAML Key类的NoteOn和NoteOff事件(从WPF Button派生)。键的颜色应该在打开时更改,并且事件应该是可订阅的,以便钢琴键盘控件的用户可以播放按下键的声音。
我可以通过将每个Midi.InputDevice传递给键盘上的每个键来实现这一点,这样每个键都可以订阅每个InputDevice的NoteOn和NoteOff事件,然后依次提出自己的NoteOn和NoteOff事件但问题是这就是PianoKeyboard控件(一个包含Keys的ItemsControl)及其嵌套的Key控件都与midi-dot-net的实现紧密耦合。如果我必须这样做,我会,但似乎应该有更好的方法在WPF中将midi-dot-net的依赖性移到调用堆栈中更高的位置。
我有太多的代码要完全粘贴到这里并且仍然可读,所以这里是我正在使用的一个DataTemplates作为我的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按钮(例如鼠标点击),那么如何触发按钮而不将其连接到按钮派生类的按钮?
答案 0 :(得分:1)
您可以通过编程方式提升Click
事件:
button1.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
答案 1 :(得分:0)
我认为这可以帮助您根据所调用的事件调用特定的Metod。
<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"
答案 2 :(得分:0)
我会做一个MIDI监听器服务单例,它可以监听所有midi事件,更新键盘状态存储库,它会显示绑定到键盘控件的视图模型......但我真的没有看到你的程序结构,所以它是不容易说。
将你的xaml中的midi事件绑定到包装器midi.net似乎不是LOB方式,因为你将gui链接到midi.net ...
顺便说一句,On / Off,还不行,你需要“按下”按键是否按下状态??