Взаємодія Metro з користувачем

ОС Windows 8 однаково добре працює з мишею, пером і жестами Це дає додаткові переваги для користувачів, але вимагає серйозних змін в моделі подій, на які відповідає код розробника у відповідь на дії користувачів

Відзначимо, що подій миші в WinRT немає Адже якщо розглядати події миші окремо від подій, повязаних з дотиками, то розробник буде змушений писати додаткових код, що обробляє обидва типи подій Виділено три типи існуючих подій:

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Події, повязані з натисканнями (пальцем, мишею або пером)

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Події, повязані з жестами (поворот, переміщення, масштабування)

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Події, повязані з переміщеннями покажчика (миша, палець або перо)

Кожна з груп дозволяє вирішувати певні завдання Наприклад, за допомогою натискань ми можемо контролювати появу контекстного меню або елементарні натискання на елементах управління За допомогою жестів можна масштабувати інтерфейс, рухати обєкти по екрану, перемикатися між різними режимами масштабування Останній набір подій дозволяє стежити за поведінкою курсору (пальця, пера) для малювання графічних примітивів або подібних завдань Розглянемо кожну групу подій окремо

Почнемо наш огляд з подій, повязаних з натисканнями Існує чотири події:

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Tapped – Дозволяє визначити клацання У випадку роботи з мишею це клацання лівої кнопки миші, а в разі роботи з пальцем – просте торкання (з відпуском пальця)

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp DoubleTapped – Подія, аналогічне попередньому, але визначає подвійне клацання У Platform Preview подібної події не було, але вже в бета-версію платформи його вирішили додати, хоча необхідність в ньому і неочевидна

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Holding  – Дозволяє визначити подія, повязана з утриманням правої кнопки миші або пальця на одному місці екрана Теоретично саме у відповідь на цю подію можна відображати контекстне меню, але в більшості випадків це робиться у відповідь на наступне подія

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp RightTapped  – Дозволяє обробити подія, яка для миші асоціюється з клацанням правою кнопкою миші, а в разі роботи з пальцем або пером – відхід пальця або пера від екрану після утримання Іншими словами, подія RightTapped може бути згенеровано після події Holding в момент звільнення пальця або іншого пристрою введення

Слід зазначити, що для генерації цих подій необхідно, щоб елемент мав встановлені вtrue   такі властивості, якIsTapEnabled, IsDoubleTapEnabled,   IsHoldingEnabled,   IsRightTapEnabled   відповідно Але оскільки в основі інтерфейсу Windows 8 лежить його чуйність на взаємодію з користувачем, то за замовчуванням всі ці властивості встановлені в true

Всі перераховані вище події передають в обробник параметр, однією з властивостей якого є PointerDeviceType Ця властивість може приймати одне з трьох значень: Mouse, Touch, Pen Тобто Ви завжди можете визначити, з чим працює користувач

Найскладнішим є подія Holding, Так як воно має на увазі роботи з декількома станами Нижче наведено невеликий блок коду, який демонструє обробку всіх станів:

private void Grid_Holding(object sender, HoldingRoutedEventArgs e)

{

switch (eHoldingState)

{

case WindowsUIInputHoldingStateStarted:

.

break

case WindowsUIInputHoldingStateCompleted:

.

break

case WindowsUIInputHoldingStateCanceled:

.

break

}

}

Як видно з коду, у розробника є можливість виконати якісь дії (активувати анімацію, додати будь візуальне оформлення) в момент утримання пальця або миші, а потім завершити дію, що передбачається подією При цьому користувач може відвести палець або мишу убік і згенерувати стан Canceled

Друга група подій дозволяє реагувати на жести Ось ці події:

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp ManipulationStarting  – Це подія дозволяє щось зробити до початку маніпуляції Звичайно мова йде про ініціалізації змінних, необхідних для маніпуляції

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp ManipulationStarted – Подія дозволяє сигналізувати про те, що користувач почав виконувати маніпуляцію з обєктом

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp ManipulationDelta    – Основна подія, яке доводиться обробляти Дозволяє визначити всі необхідні параметри маніпуляції (поворот, переміщення, масштабування) і застосувати їх до поточного обєкту

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp ManipulationCompleted   – Подія сигналізує про завершення маніпуляції

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp ManipulationInertiaStarting – Це подія корисно, якщо ми плануємо додати деяку інерцію до дій користувача Тут можна встановити необхідні параметри

Отже, якщо з подіями все ясно, поки незрозуміло, як визначити той чи інший жест Очевидно, інформація прихована в параметрах обробників подій Але перш ніж обробляти чи інша подія, необхідно вказати, який з типів маніпуляцій ми хочемо обробляти Базуючись на інструкціях розробника, система буде збирати ту чи іншу інформацію, надаючи її тільки для обєктів, які цікавлять (Щоб уникнути зайвих обчислень) Вказати тип оброблюваної маніпуляції (режим) можна за допомогою властивості ManipulationMode Тут можна відключити збір параметрів, вказати конкретний вид маніпуляції (з інерцією або без неї) або обробляти всі типи Режим можна задати і при обробці подіїManipulationStarting Для цього в параметрі обробника цієї події є спеціальне властивість Mode

Задавши режим, можна переходити до визначення жестів Інформацію про жестах можна отримати за допомогою параметра обробника події ManipulationDelta Другий параметр цього обробника має чудове властивість Delta, яке, в свою чергу, містить декілька корисних властивостей:

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Rotation – Задає кут повороту (в підказці написано, що в градусах,

а насправді в радіанах)

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Expansion – Визначає зміна відстані між двома точками дотику в пікселях Дана властивість можна використовувати для організації масштабування

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Translation – Задає зміни координат X і Y Дозволяє реалізувати переміщення обєкта

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp Scale – Визначає зміна відстані між двома точками дотику у відсотках

Знаючи значення перерахованих вище властивостей, ми можемо застосувати до обєкта всі необхідні трансформації

Нижче показаний приклад коду, який дозволяє виконувати обертання зображення навколо його центральної точки Ось як виглядає вміст сторінки XAML:

&ltCanvas Background=&quot{StaticResource ApplicationPageBackgroundBrush}&quot&gt

&ltImage Source=&quotDSC01707JPG&quot Height=&quot300&quot Width=&quot400&quot Name=&quotimg&quot ManipulationMode=&quotRotate&quot &quot ManipulationDelta=&quotImage_ManipulationDelta&quot&gt

&lt/Image&gt

&lt/Canvas&gt

А ось і сам код, який створює необхідну трансформацію і змінює її всякий раз, коли відбувається зміна параметра Rotation (ми включили тільки режим Rotation в нашому коді XAML):

public BlankPage()

{

thisInitializeComponent()

RotateTransform tr = new RotateTransform()

{

Angle = 0,

CenterX = imgActualWidth / 2, CenterY = imgActualHeight / 2

}

imgRenderTransform = tr

}

private void Image_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)

{

RotateTransform rt = imgRenderTransform as RotateTransform rtAngle += eDeltaRotation * 180 / MathPI

eHandled = true

}

Остання група подій повязана з покажчиком і найбільша:

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PointerPressed – Визначає момент натискання покажчика

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PointerReleased – Визначає момент звільнень покажчика

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PointerWheelChanged – Реагує на зміну позиції, повязаної з прокруткою (зазвичай коліщатка миші)

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PointerMoved  – Дозволяє реагувати на переміщення покажчика

(В натиснутому стані)

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PointerEntered – Дозволяє визначити, що покажчик потрапив в межі обєкта

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PointerExited – Дозволяє визначити, що покажчик покинув межі обєкта

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PointerCaptureLost – Відбувається в тому випадку, коли покажчик перейшов в інше вікно (наприклад, одне вікно знаходиться у прикріпленому режимі, а інше – в режимі Filled)

·&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp PointerCanceled – Показує, що покажчик вийшов за межі екрану

Розглянемо невеликий приклад, який дозволяє малювати на екрані прямі лінії Усередині XAML ми оголосимо простий елемент Canvas:

&ltCanvas Name=&quotLayoutRoot&quot

Background=&quot{StaticResource ApplicationPageBackgroundBrush}&quot PointerPressed=&quotCanvas_PointerPressed_1&quot PointerMoved=&quotCanvas_PointerMoved_1&quot PointerReleased=&quotLayoutRoot_PointerReleased&quot&gt

&lt/Canvas&gt

А код дозволить встановлювати початкову точку для промальовування ліній і додавати нові лінії у міру просування покажчика:

Point startPoint = null

private void Canvas_PointerPressed_1(object sender, PointerEventArgs e)

{

startPoint = eGetCurrentPoint(LayoutRoot)Position

}

private void Canvas_PointerMoved_1(object sender, PointerEventArgs e)

{

if (startPoint = null)

{

Line l = new Line()

lX1 = ((Point)startPoint)X lY1 = ((Point)startPoint)Y

startPoint = eGetCurrentPoint(LayoutRoot)Position lX2 = ((Point)startPoint)X

lY2 = ((Point)startPoint)Y

lStroke = new SolidColorBrush(ColorsRed)

LayoutRootChildrenAdd(l)

}

}

private void LayoutRoot_PointerReleased(object sender, PointerEventArgs e)

{

startPoint = null

}

Сергій Лутай, Сергій Байдачний, Windows 8 для C # розробників

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*