Posts Tagged ‘Events’

Gotcha: WPF UserControl SizeChanged event not firing at resizing

Useful to know:

If you set the Width and Height on the UserControl though, you have set a fixed size and thus even if its parent tool window changes size, the UserControl never will.  You should not set Width and Height on the UserControl if you want that event to be raised as the parent tool window changes size.


Suggestion: property and event setting block attached to C# type instance

Instead of having to write in C#

      speechRecognizer = CreateSpeechRecognizer();
      if (speechRecognizer != null)
        speechRecognizer.SomeProperty = someValue;
        speechRecognizer.SomeOtherProperty = someOtherValue;
        speechRecognizer.SpeechRecognized += SpeechRecognized;
        speechRecognizer.SpeechHypothesized += SpeechHypothesized;
        speechRecognizer.SpeechRecognitionRejected += SpeechRecognitionRejected;

I’d prefer to write:

      speechRecognizer = CreateSpeechRecognizer() {
        SomeProperty = someValue,
        SomeOtherProperty = someOtherValue,
        SpeechRecognized += SpeechRecognized,
        SpeechHypothesized += SpeechHypothesized,
        SpeechRecognitionRejected += SpeechRecognitionRejected

that is after any Type I’d like to be able to add {…} block with assignments to its properties, like I can do when I create a new type.

Do note that I also would like this syntax and the existing new Type(…) {…} syntax (which is a subset of this one) to support assignment and removal of event handlers, not just setting of properties, as shown in the example above

If you like this suggestion, vote it up at:

Gotcha: MarkerReached event of MediaElement returns new Markers

I just checked in the implementation code for a new feature for ClipFlair Studio’s Captions/Revoicing component:

When playing back recorded (or loaded from a WAV or MP3 file) audio for a caption/revoicing entry, the playback is now limited to the duration of the respective caption, (End-Start) time that is (btw that component has a duration column too that is hidden by default and can be shown by flipping it with the gear button on its titlebar and selecting the respective option to show the column).

The original audio is not affected and is stored in whole inside the saved state of the component/activity, so that you can adjust the caption entries timerange at any time to fit all or part of that recorded audio entry if you wish.

Will see into adding an “Limit playback” option to the backpanel of that component (it will default to true/checked) for any ClipFlair activities that don’t use the Start/End/Duration columns (e.g. if some activity just wants a grid of Captions and Audio entries for practicing and maybe for comparing to audio samples provided by the activity author or teacher at the optional “Comments (Audio)” column).

While implementing this feature, there were some “gotchas” that caused me some headache to spot:

1) When MediaOpened event is called by the MediaElement control, the Markers collection has just been reset and you need at that point to add your TimelineMediaMarker that will notify you when the playback limit point has been reached to stop the playback. In the case above this event is called after recording some audio or loading some WAV or MP3 audio file at an AudioRecorderControl (one is used at each row of the captions grid)

2) One shouldn’t remove an added marker at MediaEnded or MediaFailed events. This is since those will fire at each revoicing entry playback, whereas the MediaOpened while only occur once when the Audio property is populated at the AudioRecorderControl. As I mention above, MediaElement clears the Markers collection every time new content is loaded to it, so we need not worry about removing the marker we had added before.

3) Maybe the least obvious issue and the one that caused me most of headache to spot was that the MediaElement’s MarkerReached event gets back a MediaMarker that isn’t the same Marker instance as the one you had added to the Markers collection. So you have to use the Text property of the marker when you create it and then compare with the text from the one you got in the event to see if they are equal strings (btw, when C# compares strings it does it by content even if you use == instead of Equals method, unlike Java, where you shouldn’t use == to compare strings)

Gotcha: MediaElement must be in visual tree for MediaOpened, MediaEnded to be fired

At ClipFlair’s AudioRecorderControl (used in Captions/Revoicing component of ClipFlair Studio), I use the following code to initialize a MediaElement to use for playback.

After a long time a found out that if the MediaElement is not in the visual tree (for example defined in XAML, or defined in code and then added to the visual tree), then it will not always fire MediaOpened and MediaEnded events, which are crucial if you want to have a two-state Play/Stop button (a ToggleButton).


public MediaElement Player
{   get { return player; }   
set {    
if (player != null) {      
player.MediaOpened -= MediaElement_MediaOpened;
player.MediaEnded -= MediaElement_MediaEnded;    

player = value;

if (player != null)  {      
player.MediaOpened += MediaElement_MediaOpened;
        player.MediaEnded += MediaElement_MediaEnded;

       player.AutoPlay = false;
       player.PlaybackRate = 1.0;
       player.Balance = 0;
       Volume = DEFAULT_VOLUME;  
  } }


protected void MediaElement_MediaOpened(object sender, RoutedEventArgs e)
try   {    
//player.Position = TimeSpan.Zero;     
player.Stop(); //this stops current playback (if any) and rewinds
}   catch (Exception ex)   {    
PlayCommandUncheck(); //depress playback toggle button
//don't talk to ToggleButton directly    
Status = MSG_PLAY_FAILED + ex.Message;  
} }

protected void MediaElement_MediaEnded(object sender, RoutedEventArgs e)
  PlayCommandUncheck(); //depress play button to stop playback
//don't talk to ToggleButton directly }

Gotcha: MediaElement AutoPlay faster than doing Play at MediaOpened

Just added the following comment to:

Managed Media Helpers contains the very useful Mp3MediaSource class for .NET / Silverlight / Windows Phone.

Added compile-time SWITCHES and respective code to Silverlight demo code for PRELOAD (into memory stream) and AUTOPLAY (this was a bit tricky, need to call Play at MediaOpened event, not right after setting the source to the MediaElement).

Also seems to be 2-3 sec slower than AutoPlay (!) irrespective of using PRELOAD. Maybe it is faster to set the source again every time you want to play and just keep AutoPlay=true

Update: had a bug at the following code, obviously you first must set the MediaOpened event handler, then set the Source to the MediaPlayer. Also, one could set that handler once at the InitializeComponent method.


// <copyright file="Page.xaml.cs" company="Larry Olson">
// (c) Copyright Larry Olson.
// This source is subject to the Microsoft Public License (Ms-PL)
// See
// All other rights reserved.
// </copyright>
// Edited by George Birbilis (

#define AUTOPLAY
//#define PRELOAD

namespace Mp3MediaStreamSourceDemo
  using Media;
  using System;
  using System.IO;
  using System.Windows;
  using System.Windows.Controls;

    /// <summary>
    /// A Page of a Silvelight Application.
    /// </summary>
    public partial class Page : UserControl
        /// <summary>
        /// Initializes a new instance of the Page class.
        /// </summary>
        public Page()

            me.Volume = 1.0; //set max volume
            #if !AUTOPLAY
            me.AutoPlay = false;

             me.MediaOpened += (s, e) =>
                //me.Position = TimeSpan.Zero;
                me.Stop(); //this stops current playback (if any) and rewinds back to start
                //me.PlaybackRate = 1.0;
                catch (Exception ex)

        /// <summary>
        /// Event handler for the Button on the Page.
        /// </summary>
        /// <param name="sender">
        /// The button which was clicked.
        /// </param>
        /// <param name="e">
        /// The state when this event was generated.
        /// </param>
        private void OpenMedia(object sender, RoutedEventArgs e)
            OpenFileDialog ofd = new OpenFileDialog();

            Stream data = ofd.File.OpenRead();

            #if PRELOAD
            Stream m = new MemoryStream((int)ofd.File.Length);
            m.Position = 0;
            data = m;


             Mp3MediaStreamSource mediaSource = new Mp3MediaStreamSource(data);     

Gotcha: OnLostMouseCapture always called by CaptureMouse at WPF

It seems that CaptureMouse is behaving differently in WPF and Silverlight, in that in the former one it immediately calls OnLostMouseCapture at a Visual, whereas in Silverlight it doesn’t get called if the element didn’t have the mouse capture already (btw, in Silverlight that method is at a UIElement – there is no Visual ancestor as in WPF).

    #region --- Events ---

    private void OnMouseLeftButtonDown(object source, MouseButtonEventArgs e)
      if (IsMoveToPointEnabled)
        CaptureMouse(); //must do before setting dragging=true, since WPF seems
//to be always calling OnLostMouseCapture on all
//controls, even if they didn't have the mouse capture
dragging = true; //always set, we might not make it to capture the mouse } } private void OnMouseLeftButtonUp(object source, MouseButtonEventArgs e) { ReleaseMouseCapture(); dragging = false; //always clear, in case we never had the mouse capture } protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (dragging && IsMoveToPointEnabled) MoveThumbToPoint(e.GetPosition(this)); } protected override void OnLostMouseCapture(MouseEventArgs e) { base.OnLostMouseCapture(e); dragging = false; //set dragging to false whatever the value of
//IsMoveToPointEnabled (may have changed while dragging)
} #endregion


The rest of the code of the SliderExt class that I’ve just added to ClipFlair codebase is below, where … is where the code region that was quoted above goes. This class is a descendent of Slider and implements IsMoveToPointEnabled property for Silverlight (in WPF that property exists), plus in WPF it fixes the behavior of the control so that when that property is set, it not only supports moving the slider thumb to the point on its track where mouse button was held down (instead of stepping up/down as is usually done in scrollbars), but also supports dragging from any point in the slider track which WPF’s implementation of IsMouseToPointEnabled didn’t do (it only allowed to drag from the thumb).

//Project: ClipFlair (
//Filename: SliderExt.cs
//Version: 20140313

using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace SliderExtLib
  public class SliderExt : Slider

    public SliderExt()

      //peek into mouse button events (even handled ones)
new MouseButtonEventHandler(OnMouseLeftButtonDown), true); AddHandler(MouseLeftButtonUpEvent,
new MouseButtonEventHandler(OnMouseLeftButtonUp), true); } #region --- Fields --- protected bool dragging; #endregion #region --- Properties --- public bool IsMoveToPointEnabled //WPF has this prop (hiding it), doesn't
//implement move to point if you click and drag on the track instead of thumb
{ get { return (bool)GetValue(IsMoveToPointEnabledProperty); } set { SetValue(IsMoveToPointEnabledProperty, value); } } public static readonly DependencyProperty IsMoveToPointEnabledProperty = DependencyProperty.RegisterAttached("IsMoveToPointEnabled", typeof(bool), typeof(SliderExt),
new PropertyMetadata(false)); #endregion #region --- Methods --- private void MoveThumbToPoint(Point p) { if (Orientation == Orientation.Horizontal) Value = p.X / ActualWidth * Maximum; else //if (Orientation == Orientation.Vertical) Value = p.Y / ActualHeight * Maximum; } #endregion



The incentive of making such a slider was for using it at the ColorPicker control I’ve just added to the ClipFlair codebase.

HowTo: Perform action after page child controls are databound

While creating metadata entry/update pages for ClipFlair’s Activity and Clip Galleries I had the problem of figuring out how to do some initialization (from XML data, loaded from a filename based on the 1st item of a DataBound control), after all child controls of the Page have been databound (from XmlDataSource).

Seems others have asked about that too, so I contributed my solution:

Based on Page Life Cycle Events article I used:

protected void Page_PreRenderComplete(object sender, EventArgs e)
  if (!IsPostBack) //only at 1st load

protected void UpdateSelection()

protected void listItems_SelectedIndexChanged(object sender, EventArgs e)

where UpdateSelection was loading XML data from a file selected at a dropdown list (which at start is pointing to index 0) and needed some CheckBoxLists on the page to have first gotten their items from other XML files so that they would allow the code to check items on them based on the XML data (from then on UpdateSelection is just getting called at the dropdownlist SelectedIndexChanged event – those do PostBacks so at PreRenderComplete we ignore them to avoid doing UpdateSelection twice)

Gotcha: var x = x() in Javascript gives “Object Expected” error

At ClipFlair Studio (a Silverlight app), I had some time ago implemented a confirmation warning upon user trying to close the webpage (when it was running inside the web browser), which then had stopped functioning. It seems at some refactoring I had added code like the following:

var activityView = activityView();

and it was failing with error “Object Expected” (and even worse this was done silently – had to use browser’s debugging tools to catch it – because the respective code was running at onbeforeunload browser window event).

Such code would be fine in C#, but in Javascript it seems that a local variable with name x hides a function named x (with any number of parameters in its definition). This is obviously because functions are first-class objects in Javascript and can be treated like variables themselves too.

All started working again fine after changing that code to:

var a = activityView();

Below is the respective block of Javascript code included in a script tag at the webpage that hosts the Silverlight control. Note the “control.content.activityWindow”, where “activityWindow”  is accessed via the Silverlight HTMLBridge (that object – that has to be marked with ScriptableType class attribute – is registered using that key via HtmlPage.RegisterScriptableObject at the Silverlight app side).

function silverlightControl() {
  return document.getElementById("silverlightControl");

function onSilverlightLoad(sender, args) {
  var control = silverlightControl();
  if (control != null)

function activityWindow() {
  var control = silverlightControl();
  if ( (control != null) && (control.content != null) )
    return control.content.activityWindow;
    return null; //need this so that it doesn't return undefined

function activityView() {
  var a = activityWindow();
  if (a != null)
    return a.GetView();
    return null; //need this so that it doesn't return undefined

function onClosing() {
  var a = activityView();
  if ( (a != null) && (a.WarnOnClosing) )
    return "Do you want to exit ClipFlair Studio?";
//else return undefined is implied (no onClosing message that is) } function onClosed() { var a = activityView(); if (a != null) a.WarnOnClosing = false; } function installEventHandlers() { window.onbeforeunload = onClosing; window.onunload = onClosed; } installEventHandlers();
%d bloggers like this: