Thursday, March 31, 2011

Workaround for some WPF features that are missing in Silverlight

I’m porting a WPF app to silverlight 2, and have come across several WPF features which are presently missing from SL. Could anyone help me with equivalents or suggest workarounds.

  1. I want to handle clicks and double clicks on a textbox embedded in a list box. The WPF implementation uses PreviewMouseLeftButtonDown/Up on a listbox control. How can this be done in silverlight, it seems that PreviewMouseLeftButtonDown/Up are missing in silverlight.

  2. I want to handle button presses (F2/Delete) on a textbox embedded in a list box. The WPF implementation uses PreviewKeyDown on a textbox control which embedded as an item in a listbox. It seems that PreviewKeyDown is missing in silverlight. The KeyDown event handler does not seem to get invoked.

  3. I want to change some appearance properties of a textbox depending on the value of some custom attached properties. The WPF implementation uses a DataTrigger to do this. How can this be done in silverlight. It seems that DataTriggers are missing in silverlight.

  4. I want to change the width of a text box depending on the Actual Width of the listbox in which the text box is contained. The WPF implementation uses RelativeSource binding. What is the silverlight equivalent, or workaround for this.

From stackoverflow
  • I'm more familiar with Silverlight than the full WPF. Please considier my responses accordingly.

    For number 2. For many keys, I check on KeyUp and KeyDown. I use KeyDown while trying to watch the entire time that the key is held down and KeyUp when it was used just once. You should know this was for a game without an individual text box.

  • For item 4, you can bind both the listbox width and the textbox width to a static resource's property so that it acts as a router for the binding. You could also use a value converter that you initialize with a reference to the listbox, then use the converter for your textbox width.

    For item 3, you could use a similar approach.

  • For item 1 and 2, the best way to get access to these input events is to create a custom TextBox deriving from the built in TextBox. Then you can override the OnKeyDown and OnMouseLeftButton down. From there you can either call the necessary code, or fire a new event. e.g.:

    public class MyTextBox : TextBox
    {
        public event MouseButtonEventHandler MySpecialMouseLeftButtonDown;
    
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            if (MySpecialMouseLeftButtonDown != null)
            {
                MySpecialMouseLeftButtonDown(this, e);
            }
            base.OnMouseLeftButtonDown(e);
        }
    }
    

    Similarly with OnKeyDown.

    Isak Savo : This is not how the Preview events works in WPF. As WPF has routed events, the preview events are tunneled from the root element (e.g. Window) down to the final receiver (e.g. Textbox) which gives higher elements the option to intercept the event before it reaches the textbox.
    KeithMahoney : Yes. Calling the event PreviewMouseLeftButtonDown was not a good idea. But it would work to solve the problem that the thread starter had. I will edit the answer to remove the source of possible confusion.

0 comments:

Post a Comment