Posts Tagged Silverlight
Multi-touch and Ink support in Silverlight
Posted by worm.NET in Silverlight on Tháng Sáu 7, 2011
Silverlight is Microsoft’s ambitious dream to provide a simple-but-powerful development platform for Rich Internet Applications (RIAs). The release of Windows Phone 7 marks Microsoft’s latest effort to broaden Silverlight’s reach to the booming portable market, where the number of users increases by millions every year. As this market requires nontraditional ways to interact with the device (you don’t expect your cell phone to have mouse and full-size keyboard, do you?), Silverlight is also empowered with new support for some of the currently “hot” technologies, including Multi-touch and Ink.
Multi-touch
Multi-touch is an exciting technology that contributed to the success of the over-popular iPhone and iPad. Though the first touch-enabled (single-touch) device has appeared long ago, it is only multi-touch that truly pushes user experience to a new level by allowing them to perform complex maneuvers with more than one finger. This can create some fancy effects such as zooming and rotating photos that were previously impossible with single-touch. With more and more devices adopting to use this technology, Silverlight of course, cannot stay out of the game. Indeed, Silverlight, since version 3.0, has officially support Multi-touch.
Multi-touch is basically an input method, and the first thing we usually think about input processing is input events. In Silverlight, the main event that we need to care about is FrameReported, declared in the Touch class. Registering this event is as simple as follow:
Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
Notice that unlike some common events such as Button.Click, FrameReported is a static event that doesn’t link to any specific instances of the Touch class (actually Touch is also static and therefore cannot have any instances!). When a device is touched, it raises this event repeatedly after a specific interval, the duration of which depends largely on the hardware being used. But for now we’ll skip the details, our interest here is how to handle this event, so let’s shift our focus to the event handler:
void OnTouchFrameReported(object sender, TouchFrameEventArgs e) { string str = ""; foreach (TouchPoint tp in e.GetTouchPoints(this)) { str += string.Format("{0}; ", tp.Position); } MessageBox.Show(str); }
Not surprisingly, it’s no different from that of a normal event. The above code simply collects the position of each touch point and displays them on the screen. There’s only one thing that needs a bit more explanation, that’s the second parameter of type TouchFrameEventArgs of the event handling method. This parameter contains useful members, including the two methods GetPrimaryTouchPoint() and GetTouchPoints(), whose names are already self-explanatory: GetPrimaryTouchPoint() returns the first touch point in the series (represented by an object of the TouchPoint class), while GetTouchPoints() returns a collection of all touch points. The TouchPoint class provides the following properties:
- Position: the coordinate of the touch point. This can be relative to another UI element (if you pass that element to GetPrimaryTouchPoint() or GetTouchPoints()) or absolute (passing null).
- Size: the size of the touch point, reflecting how strong you press your finger.
- Action: describes the user’s activity. A Down value means the user just pressed his finger on the screens, Up means the user lifted his finger, and Move means the finger was dragged.
- TouchDevice: the device that provides information about the touch. The DirectlyOver property of TouchDevice returns the topmost UI element at the touch point. This is mainly for compatibility with WPF.
Ink
Ink is a special type of content in the form of drawings created by an input device such as mouse or stylus (a pen-like input device). Silverlight provides one class, the InkPresenter, that facilitates the way you work with Ink. The ink itself is represented by a Stroke instance. Here’s the code to create an InkPresenter in XAML:
<Grid x:Name="grid"> <InkPresenter x:Name="inkPresenter" Background="White"/> </Grid>
Just as with Multi-touch, to work with Ink, you will need to know about the events. A common scenario is that in the MouseLeftButtonDown event, we’ll instantiate a new Stroke object, and continue to build up this Stroke as the user drags the device (mouse or stylus…) upon the InkPresenter with the MouseMove event, and finally complete the stroke in the MouseLeftButtonUp event. This is illustrated in the code below:
private Stroke _stroke; public MainPage() { InitializeComponent(); inkPresenter.MouseLeftButtonDown += new MouseButtonEventHandler(inkPresenter_MouseLeftButtonDown); inkPresenter.MouseMove += new MouseEventHandler(inkPresenter_MouseMove); inkPresenter.MouseLeftButtonUp += new MouseButtonEventHandler(inkPresenter_MouseLeftButtonUp); } private void inkPresenter_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { inkPresenter.CaptureMouse(); _stroke = new Stroke(e.StylusDevice.GetStylusPoints(inkPresenter)); inkPresenter.Strokes.Add(_stroke); } private void inkPresenter_MouseMove(object sender, MouseEventArgs e) { if (_stroke != null) { _stroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(inkPresenter)); } } private void inkPresenter_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { inkPresenter.ReleaseMouseCapture(); _stroke = null; }
Besides, the Stroke has many properties that allow you to format the drawing (such as changing size and color…). One great thing about Silverlight is that much of these features are accessible in both ways: declaratively (using XAML) or programmatically (using code). But this time, I’ll leave them up to you to discover.
Conclusion
Every application needs input! That’s true unless you never work on anything more complex than a Hello World program. Input can come from many sources: mouse, keyboard, multi-touch or ink… By providing support for such a broad range of input technologies, Silverlight has proven to be suitable for virtually every platform: from web to desktop to mobile computing. May it fulfill Microsoft’s dream about a world powered by Silverlight? Only time will tell but the ability to handle multi-touch and ink input natively are certainly welcome, as it not only simplifies the job of the developers, but also helps create a rich user experience that RIA once promised.
Hỗ trợ Multi-touch và Ink trong Silverlight
Posted by worm.NET in Silverlight on Tháng Một 16, 2011
Silverlight được coi như nền tảng phát triển của Microsoft cho các ứng dụng internet giàu khả năng tương tác (RIA). Không chỉ dừng lại trên trình duyệt, Silverlight cũng đang ngấp nghé thị trường thiết bị di động, đặc biệt là điện thoại thông minh. Để có thể thành công trên lĩnh vực này, chắc chắn Silverlight cần phải cung cấp cho người dùng những cách tương tác mới (ngoài chuột và bàn phím!). Thật may là bạn có thể tìm thấy trong Silverlight tất cả các hỗ trợ cần thiết cho các công nghệ đang “nóng” hiện nay, bao gồm Multi-touch và Ink.
Multi-touch
Multi-touch (hay cảm ứng đa chạm) là công nghệ cho phép người sử dụng giao tiếp với thiết bị thông qua các cử động của ngón tay và màn hình cảm ứng. Mặc dù single-touch xuất hiện trên thị trường đã lâu, nhưng sự ra đời của multi-touch mới thực sự đem lại những trải nghiệm thú vị: bạn có thể sử dụng các cử điệu của ngón tay để thực hiện các thao tác phức tạp (như phóng to, thu nhỏ) mà trước đây không thể làm được với single-touch. Siverlight hỗ trợ Multi-touch từ phiên bản 3 và cung cấp một giao diện lập trình để làm việc với công nghệ này.
Multi-touch về cơ bản là một phương pháp nhập (input), mà điều đầu tiên cần nhắc đến khi nói về xử lý nhập là các sự kiện nhập. Trong Silverlight, sự kiện chính mà ta cần quan tâm là FrameReported của lớp Touch. Touch là lớp static, do đó ta có thể đăng kí sự kiện này như sau:
Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
Nếu đã quen với cơ chế xử lý sự kiện trong C#, bạn hẳn có thể nhận ra một chút khác biệt: FrameReported là một sự kiện static và không gắn với bất kì đối tượng giao diện nào (trái với các sự kiện như Click luôn gắn với đối tượng Button cụ thể). Sự kiện này được phát sinh mỗi khi phần cứng gửi tín hiệu đến môi trường thực thi. Thời điểm phát sinh cụ thể tùy thuộc vào trình điều khiển phần cứng mà bạn sử dụng. Nhưng tóm lại thì sau khi đăng kí sự kiện trên, bạn đã có thể bắt đầu nghĩ đến chuyện xử lý nó được rồi! Phương thức xử lý sự kiện này cũng tương tự như các phương thức xử lý sự kiện thông thường khác:
void OnTouchFrameReported(object sender, TouchFrameEventArgs e) { string str = ""; foreach (TouchPoint tp in e.GetTouchPoints(this)) { str += string.Format("{0}; ", tp.Position); } MessageBox.Show(str); }
Không có gì khó khăn để đoán được ý nghĩa của đoạn code trên là hiển thị ra màn hình vị trí của các điểm chạm (touch point). Điều đáng lưu ý ở đây nằm ở tham số thứ hai của phương thức. Đây là một tham số thuộc kiểu TouchFrameEventArgs, cung cấp cho ta rất nhiều thông tin hữu ích. Trong đó phải kể đến đầu tiên là hai phương thức GetPrimaryTouchPoint() và GetTouchPoints(). GetPrimaryTouchPoint() trả về điểm chạm đầu tiên, trong khi GetTouchPoints() trả về một tập hợp tất cả các điểm chạm. Các điểm chạm này lại được thể hiện bởi lớp TouchPoint, gồm các thuộc tính quan trọng sau:
- Position: tọa độ x, y của điểm chạm. Tọa độ này có thể là tương đối so với một phần tử giao diện nào đó (nếu bạn truyền phẩn tử đó vào GetPrimaryTouchPoint() hoặc GetTouchPoints()) hoặc tuyệt đối (nếu bạn truyền null cho hai phương thức này).
- Size: kích thước của điểm chạm, phản ánh mức độ nhấn tay mạnh hay nhẹ.
- Action: mô tả hành động của người dùng, có thể là Down (khi vừa nhấn tay xuống), Up (khi vừa nhả tay) hoặc Move (di chuyển ngón tay trên màn hình)
- TouchDevice: thiết bị cung cấp thông tin về điểm chạm. Thuộc tính DirectlyOver của TouchDevice trả về phần tử giao diện nằm trên cùng tại vị trí điểm chạm. Thuộc tính này chủ yếu để đảm bảo tính tương thích với WPF.
Ink
Ink là một loại nội dung đặc biệt dưới dạng các nét vẽ được tạo ra bởi chuột hoặc một thiết bị trỏ có dạng giống cây bút (còn gọi là stylus). Silverlight cho phép thu thập loại nội dung này một cách dễ dàng với lớp InkPresenter. Thông tin về ink sẽ được lưu trữ dưới dạng Stroke. Ta có thể khai báo một InkPresenter trong XAML như sau:
<Grid x:Name="grid"> <InkPresenter x:Name="inkPresenter" Background="White"/> </Grid>
Tương tự như với Multi-touch, để làm việc với Ink, bạn sẽ cần phải quan tâm đến các sự kiện. Thông thường, trong sự kiện MouseLeftButtonDown, ta sẽ tạo một đối tượng Stroke mới, và xây dựng Stroke này khi người dùng rê thiết bị (con trỏ hoặc stylus…) trên InkPresenter với sự kiện MouseMove, cuối cùng kết thúc trong sự kiện MouseLeftButtonUp. Ý tưởng này được minh họa trong đoạn code sau:
private Stroke _stroke; public MainPage() { InitializeComponent(); inkPresenter.MouseLeftButtonDown += new MouseButtonEventHandler(inkPresenter_MouseLeftButtonDown); inkPresenter.MouseMove += new MouseEventHandler(inkPresenter_MouseMove); inkPresenter.MouseLeftButtonUp += new MouseButtonEventHandler(inkPresenter_MouseLeftButtonUp); } private void inkPresenter_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { inkPresenter.CaptureMouse(); _stroke = new Stroke(e.StylusDevice.GetStylusPoints(inkPresenter)); inkPresenter.Strokes.Add(_stroke); } private void inkPresenter_MouseMove(object sender, MouseEventArgs e) { if (_stroke != null) { _stroke.StylusPoints.Add(e.StylusDevice.GetStylusPoints(inkPresenter)); } } private void inkPresenter_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { inkPresenter.ReleaseMouseCapture(); _stroke = null; }
Ngoài ra, lớp Stroke còn có nhiều thuộc tính cho phép định dạng nét vẽ (màu sắc, kích thước…). Bạn có thể tự tìm hiểu thêm
Kết luận:
Xử lý nhập là một phần quan trọng không thể thiếu của mọi ứng dụng. Với việc hỗ trợ các công nghệ tương tác mới nhất như Multi-touch và Ink, Silverlight đã cung cấp một môi trường phát triển lý tưởng cho mọi nển tảng: dù là web, desktop, hay di động. Silverlight không chỉ đơn giản hóa công việc của các lập trình viên, mà còn góp phần mang đến cho người dùng những trải nghiệm mới đầy thú vị.