locked
Mimicking intellisense behavior RRS feed

  • Question

  • Hi

    I'm learning WPF atm and building an  editor with intellisense type functionality.

    In looking at the intellisense in vs2010, when intellisense kicks in,  each keystroke get reflected into both the textarea as well as the drop down listbox. I'm wondering how this could be implemented in WPF. For example, is it simply that the richtextbox's textchanged event is trapped and the keystroke explicitly passed onto the listbox, or could the same behaviour be achieved by some sort of declarative binding such that the listbox automatically receives the same keystroke as was keyed into the richtextbox.

    Edited - So having thought a bit more about this, one solution could be to have a simple pub/sub eventboker type. Register the edittextbox as the publisher and the listbox as a subscriber. Trap the textchanged event of the richtextbox and publish it to all of the registed subscribers. But is the XAML/WPF way? I am trying to fathom MVVM (so already have an eventbroker) as well so doing as much of this declaratively in XAML would be good!

    Thx

    Simon

    • Edited by Simon Woods Wednesday, August 11, 2010 4:59 AM Spelling
    Tuesday, August 10, 2010 11:41 AM

Answers

  • Simon,

    Mimicking IntelliSense functionality requires quite complex collaboration between controls and I doubt you can fully achieve it using XAML alone. However to begin with you can handle PreviewTextInput event on RichTextBox and use the TextComposition object to raise an identical TextInput event on the ListBox. Here is an example:

    <Window x:Class="InstelliSense.Window1"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="Window1" Height="300" Width="300">

        <Grid>

            <RichTextBox PreviewTextInput="OnTextInput"/>

            <ListBox Name="List" Margin="3,20,0,0" Height="69" Width="200"

                     VerticalAlignment="Top" HorizontalAlignment="Left">

                <ListBoxItem>First</ListBoxItem>

                <ListBoxItem>Second</ListBoxItem>

                <ListBoxItem>Third</ListBoxItem>

            </ListBox>

        </Grid>

    </Window>


    using System.Windows.Input;

     

    namespace InstelliSense

    {

        public partial class Window1

        {

            public Window1()

            {

                InitializeComponent();

            }

     

            private void OnTextInput(object sender, TextCompositionEventArgs e)

            {

                List.RaiseEvent(

                    new TextCompositionEventArgs(e.Device, e.TextComposition)

                        {

                            RoutedEvent = TextInputEvent

                        });

            }

        }

    }

    Works fine except that the ListBox steals focus after first keystroke. To fix that you can manually select the right item in the list instead of raising the event. For a more elaborate solution however an event broker may be the way to go.

     - Levi

    • Proposed as answer by Levi Haskell Wednesday, August 11, 2010 4:38 PM
    • Marked as answer by Simon Woods Thursday, August 12, 2010 6:31 AM
    Tuesday, August 10, 2010 9:25 PM

All replies

  • Simon,

    Mimicking IntelliSense functionality requires quite complex collaboration between controls and I doubt you can fully achieve it using XAML alone. However to begin with you can handle PreviewTextInput event on RichTextBox and use the TextComposition object to raise an identical TextInput event on the ListBox. Here is an example:

    <Window x:Class="InstelliSense.Window1"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="Window1" Height="300" Width="300">

        <Grid>

            <RichTextBox PreviewTextInput="OnTextInput"/>

            <ListBox Name="List" Margin="3,20,0,0" Height="69" Width="200"

                     VerticalAlignment="Top" HorizontalAlignment="Left">

                <ListBoxItem>First</ListBoxItem>

                <ListBoxItem>Second</ListBoxItem>

                <ListBoxItem>Third</ListBoxItem>

            </ListBox>

        </Grid>

    </Window>


    using System.Windows.Input;

     

    namespace InstelliSense

    {

        public partial class Window1

        {

            public Window1()

            {

                InitializeComponent();

            }

     

            private void OnTextInput(object sender, TextCompositionEventArgs e)

            {

                List.RaiseEvent(

                    new TextCompositionEventArgs(e.Device, e.TextComposition)

                        {

                            RoutedEvent = TextInputEvent

                        });

            }

        }

    }

    Works fine except that the ListBox steals focus after first keystroke. To fix that you can manually select the right item in the list instead of raising the event. For a more elaborate solution however an event broker may be the way to go.

     - Levi

    • Proposed as answer by Levi Haskell Wednesday, August 11, 2010 4:38 PM
    • Marked as answer by Simon Woods Thursday, August 12, 2010 6:31 AM
    Tuesday, August 10, 2010 9:25 PM
  • Levi ... many thx. That's very helpful. (and for the spelling correction!)

    Simon

     

    Wednesday, August 11, 2010 5:06 AM