samc
Topic Author
Posts: 94
Joined: 21 Aug 2019, 19:22

question about events + audio

07 Nov 2025, 03:10

We're having some struggles hooking up events for audio -- specifically getting them to trigger at the proper time (and not when we don't want them to trigger).

An example would be ComboBox -- we can hook into the `SelectionChanged` event to trigger audio when the selection changes, but there are weird edge cases like when we're setting up the initial user interface, the selection is changed, so you hear the audio event.

You can also get into weird situations with this on first load of the user interface when focus and other events fire, but for audio purposes we'd ideally like to ignore them, and only change things as a response to user input.

Has anyone found good patterns to deal with these edge cases?

thanks,
sam
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: question about events + audio

11 Nov 2025, 13:10

Hi Sam,

One of the things you can do to avoid that the first SelectionChanged launched during initialization plays the sound is to keep the PlaySoundAction disabled until the ComboBox gets loaded:
<ComboBox ...>
  <b:Interaction.Triggers>
    <b:EventTrigger EventName="SelectionChanged">
      <b:PlaySoundAction x:Name="SelectSoundAction" Source="Sounds/select.mp3" IsEnabled="False"/>
    </b:EventTrigger>
    <b:EventTrigger EventName="Loaded">
      <b:ChangePropertyAction TargetName="SelectSoundAction" PropertyName="IsEnabled" Value="True"/>
    </b:EventTrigger>
  </b:Interaction.Triggers>
</ComboBox>
Another approach some clients are using is to define your own attached properties that can do all the necessary checks in code, by manually attaching/detaching to the desired events of the control when it gets loaded/unloaded. Here you're in full control of what to do to play the sounds.
<ComboBox local:SoundManager.SoundProfile="Default" .../>
public static class SoundManager
{
  public static readonly DependencyProperty SoundProfileProperty = DependencyProperty.RegisterAttached(
    "SoundProfile", typeof(string), typeof(SoundManager), new PropertyMetadata(string.Empty, OnSoundProfileChanged));
    
  private static void OnSoundProfileChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
    if (d is FrameworkElement element)
    {
      element.Loaded += OnElementLoaded;
      element.Unloaded += OnElementUnloaded;
    }
  }
  
  private static void OnElementLoaded(object sender, RoutedEventArgs e)
  {
    if (sender is ButtonBase button) { /* hook to MouseEnter, GotFocus, Click events? */ }
    else if (sender is Selector selector) { /* hook to SelectionChanged event? */ }
    // else ...
  }
}
Happy to hear what other users are doing :)

Hope this helps.

Who is online

Users browsing this forum: No registered users and 3 guests