Ink Enabled Form Analysis (auto commit to textboxes) RRS feed

  • General discussion

  • Hello,

    Following my question What is the best way to Ink-enable a complex form?  I looked for the best way to commit the writings into the textboxes, and here is the way i did :

    Since i'm using the framework 3.5 and WPF in my application, i use the DispatcherTimer, which works pretty well and easily finally :-).

    here is how I used it :

    Code Block
    public partial class MainWindow : System.Windows.Window

    private DispatcherTimer myDispatcherTimer;

    public MainWindow()
              this.Loaded += new RoutedEventHandler(Window1Loaded);
    myDispatcherTimer =
    new DispatcherTimer(new TimeSpan(0, 0, 1),DispatcherPriority.Normal,new EventHandler(StrokesAnalyze),this.Dispatcher);


    private void StrokesAnalyze(object sender, EventArgs e)
    // Here you treat and analyze your strokes

    private void AnalyzeTimerLaunch(object sender, MouseButtonEventArgs e)

    private void AnalyzeTimerStop(object sender, MouseButtonEventArgs e)
                Console.WriteLine("STOP TIMER");
                myDispatcherTimer.IsEnabled = false;

    The AnalyzeTimerStart and AnalyzeTimerStop are raised on the MouseUp and PreviewMouseDown Events (PreviewMouseDown is to be used instead of MouseDown, here is the explanation : Unable to detect MouseUp event in InkCanvas thank you Stefan Wick (again!) ) So when the user stops writing, the DispatcherTimer starts. Then, either the user doesn't write for more than 1 second and the analysis is launched, or he starts to write before the time is up and the DispatcherTimer is stopped.
    This way, the strokes are automatically analysed and the user dont need to push any button to validate (in my case, to analyse the writings and commit them into the textboxes)

    If you get a better way to do this, or if mine has any drawbacks that can be avoided, please let me know. I hope this will be usefull to some developers here, it's my first contribution here though :-)

    Friday, January 4, 2008 3:27 PM

All replies

  • Hi Stephane,


    thanks for posting your code here.


    One suggestion for an optimization:

    With your current approach, the text insertion happens 1+x seconds after the last stroke has been collected. The 'x' can be quite noticable if there's a lot of complex ink. You can minimize 'x' by taking advantage of background analysis.


    Basically here is how it works:

    - after each stroke, update the InkAnalyzer and call BackgroundAnalyze

    - in the ResultsUpdated event, get the current result and cache it

    - if your 1 sec timeout fires, check InkAnalyzer.IsAnalyzing

    - if it's false, insert the cached result

    - it it's true, wait for the next ResultsUpdated event and then insert the result



    Saturday, January 5, 2008 5:36 PM
  • :-) Thank you Stefan, I actually already saw this BackgroundAnalyze method and i was keeping in mind to implement it once the simple way works fine.

    I have some other issues about the recognition that i'm not sure how to handle.
    To enhance the recognition, i use analysis hints. So as you previously advised me, i have a grid where are my components plus an inkcanvas, and I use the Z-index to put the textboxes under the inkcanvas.
    My problem is to find the coordinates of the textboxes to create the rectangle for the analysis hint.
    Is there a way to find the coordinates of my tetboxes AND to keep using the grid positioning facilities (RowDefinition and ColumnDefinition), do I have to use a simple Canvas like you did in your samples :

    Code Block

    <Window x:Class="InkEnabledForm.Window1"



            Title="InkEnabledForm" Height="500" Width="500">


        <Canvas Name="form" Width="300" Height="400" Background="AntiqueWhite">

          <InkCanvas Width="{Binding ElementName=form,Path=ActualWidth}"

                     Height="{Binding ElementName=form,Path=ActualHeight}"

                     Panel.ZIndex="3" Background="Transparent"/>

          <!-- elements with z-index < InkCanvas appear behind the ink -->

          <TextBox Panel.ZIndex="0" Canvas.Left="20" Canvas.Top="20" Width="80"/>

          <TextBox Panel.ZIndex="1" Canvas.Left="20" Canvas.Top="100" Width="150"/>

          <TextBox Panel.ZIndex="2" Canvas.Left="200" Canvas.Top="200" Width="80"/>

          <!-- elements with z-index > InkCanvas appear in front of the ink -->

          <Button Panel.ZIndex="4" Canvas.Left="150" Canvas.Top="220">Click Me</Button>

          <Button Panel.ZIndex="5" Canvas.Left="150" Canvas.Top="270">Click Me</Button>






    Monday, January 7, 2008 10:00 AM
  • Nevermind, i'll use a Canvas, it will be much easier Smile
    Monday, January 7, 2008 10:31 AM
  • I agree that using a Canvas with absolute-positioning for the TextBoxes sounds like a fine approach for your scenario.


    Just for completeness sake:

    If you used a Grid (or other non-absolute layout mechanism), you can determine the up-to-date position of the TextBoxes by listening to the LayoutUpdated event off your layout panel. In that event handler you can use the "TranslatePoint" method on each TextBox to find its position relative to the original of your inking surface. With this position information you can then create the corresponding AnalysisHint on the InkAnalyzer.



    Wednesday, January 9, 2008 6:54 AM
  • Thank you very much, I will probably try to use this in next versions Smile.
    But the easy way with canvas is working well, that will do it for now!

    Monday, January 14, 2008 10:02 AM