Browse DevX
Sign up for e-mail newsletters from DevX


Ink And The Database : Page 2

Unless your battery is really, really good, you'll eventually want to store your Ink. Simple file storage or XML serialization is sometimes sufficient, but usually, you'll want to move Ink into and out of a relational database. Here's how.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

DataBinding and Ink
Create a new Windows application called Example2. In the Solution Explorer, add your reference to the Microsoft Tablet PC API and add a New Item, choosing Dataset. When the Dataset Designer appears, drag the Ink table from the Server Explorer onto the Designer. Switch back to the Visual Designer for Form1 and drag a Panel, BindingNavigator, a BindingSource, and an instance of your DataSet Designer-generated InkTableAdapter onto the Designer. Set the DataSource of the BindingSource to your just-created DataSet and set the BindingSource of the BindingNavigator to your just-created BindingSource.

Open the code view for Form1 and add io and isDisposed members as in Example1. Initialize these as before, and additionally, add databinding code like this:

public Form1() { InitializeComponent(); io = new InkOverlay(panel1); io.Enabled = true; Binding inkBinding = new Binding("Tag", bindingSource1, "Ink", true); inkBinding.Format += new ConvertEventHandler( inkBinding_Format ); panel1.DataBindings.Add(inkBinding); inkTableAdapter1.Fill(dataSet1.Ink); }

This code binds the Ink value of bindingSource1 to the Tag property of the object that ends up owning the Binding (it will be panel1, as seen in the second-to-last line of the snippet). The Tag property is a general-purpose field that can be used for custom data-binding, as you're doing here. You need custom data-binding because you cannot automatically bind the Ink property of the io overlay to the byte[] coming through the BindingSource. (Maybe in a future SDK, there will be an automatic conversion between the two types.) To affect the custom code, attach a ConvertEventHandler to the Format event of the inkBinding Binding. Finally, add the new Binding to the DataBinding of panel1 and fill dataSet1 with the InkTableAdapter.

The ConvertEventHandler delegate you defined is inkBinding_Format:

void inkBinding_Format (object sender, ConvertEventArgs e) { //Is this the DB byte array? if (e.Value.GetType() == typeof(byte[])) { Ink ink = new Ink(); byte[] inkBytes = (byte[])e.Value; ink.Load(inkBytes); lock (io) { io.Enabled = false; io.Ink = ink; io.Enabled = true; } } }

This is reminiscent of the code in Listing 2: a new Ink object is created, an inkBytes variable is filled with the data, and ink.Load() puts them together. Most importantly, you lock and disable the InkOverlay before assigning the newly created Ink to it.

Every navigation event creates a new Ink object, even when the corresponding record has been visited before. There's a definite trade-off here: convenience versus memory and processor resources.
Implement the Dispose(bool) pattern as previously discussed, run the application, and you should be able to move forward and backward through the Ink objects created in the Example1. It's very convenient, very easy, but be clear about what you have. The database sucked down all of the byte arrays and stored them in dataSet1. Additionally, every navigation event creates a new Ink object, even when the corresponding record has been visited before. There's a definite trade-off here: convenience versus memory and processor resources.

To avoid client-side resource strain, there are two strategies:

  • Client-side caching strategies
  • Server-side query strategies
Client-side caching involves creating a Collection of Ink objects when the data is initially brought down from the server and then data-binding to that. This reduces the per-navigation event performance and memory-management penalty, but does not reduce the memory footprint of the DataSet, which is likely to be the largest problem when dealing with hundreds or thousands of returned records.

Thanks for your registration, follow us on our social networks to keep up-to-date