Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Bemeneti adatok fogadása, feldolgozása és kezelése a Windows-alkalmazásokban lévő rámutató eszközökről (például érintés, egér, toll/toll és érintőpad).
Fontos
Egyéni interakciók csak akkor hozhatók létre, ha egyértelmű, jól meghatározott követelmény áll fenn, és a platformvezérlők által támogatott interakciók nem támogatják a forgatókönyvet.
Ha testre szabja a Windows-alkalmazás interakciós felületeit, a felhasználók elvárják, hogy konzisztensek, intuitívak és felderíthetőek legyenek. Ezért javasoljuk, hogy a platformvezérlők által támogatottakra modellezi az egyéni interakciókat. A platformvezérlők teljes Windows app felhasználói interakciót biztosítanak, beleértve a standard interakciókat, az animált fizikai effektusokat, a vizuális visszajelzéseket és az akadálymentességet.
Fontos API-k
Hivatkozások
A legtöbb interakciós élmény általában azzal jár, hogy a felhasználó azonosítja azt az objektumot, amellyel kapcsolatba kíván lépni, és olyan beviteli eszközökön keresztül mutat rá, mint az érintés, az egér, a toll/toll vagy az érintőpárna. Mivel az ezen bemeneti eszközök által biztosított nyers Human Interface Device (HID) adatok számos közös tulajdonságot tartalmaznak, az adatokat előléptetik és egységes bemeneti verembe konszolidálják, majd eszközfüggetlen mutatóadatokként jelenítik meg. A Windows-alkalmazások ezután anélkül használhatják ezeket az adatokat, hogy a használt bemeneti eszköz miatt kellene aggódniuk.
Megjegyzés:
Az eszközspecifikus adatok a nyers HID-adatokból is elő lesznek léptetve, ha az alkalmazásnak szüksége van rá.
A bemeneti verem minden bemeneti pontját (vagy kapcsolatát) egy Pointer objektum jelöli, amely a PointerRoutedEventArgs paraméteren keresztül érhető el a különböző mutatóesemény-kezelőkben. Többtollú vagy többérintéses bemenet esetén a rendszer minden érintést vagy kapcsolódási pontot egyedi beviteli mutatóként kezel.
Mutatóesemények
A mutatóesemények olyan alapvető információkat fednek fel, mint a bemeneti eszköz típusa és észlelési állapota (tartományban vagy kapcsolatban), valamint a kiterjesztett információk, például a hely, a nyomás és a kapcsolat geometriája. Emellett bizonyos eszköztulajdonságok is elérhetők, mint például a felhasználó által lenyomott egérgomb vagy a toll radírhegyének használata. Ha az alkalmazásnak különbséget kell tennie a bemeneti eszközök és képességeik között, tekintse meg a bemeneti eszközök azonosítását.
A Windows-alkalmazások a következő mutatóeseményeket figyelhetik:
Megjegyzés:
A mutató bemenetének egy adott felhasználói felületi elemhez való korlátozásához hívja meg a CapturePointert az adott elemen egy mutatóesemény-kezelőn belül. Ha egy elem rögzít egy mutatót, csak az objektum fogadja a mutató bemeneti eseményeit, még akkor is, ha a mutató az objektum határoló területén kívülre kerül. Az IsInContact (egérgomb lenyomva, érintés vagy tollal érintkezik) igaznak kell lennie ahhoz, hogy a CapturePointer sikeres legyen.
| Event | Description | |
|---|---|---|
| PointerCanceled | Akkor fordul elő, ha a platform megszakít egy mutatót. Ez a következő esetekben fordulhat elő: • Az érintéses mutatókat a program megszakítja, ha tollat észlel a bemeneti felület tartományán belül. • A rendszer 100 ms-nál hosszabb ideig nem észlel aktív kapcsolatot. • A monitor/kijelző módosul (felbontás, beállítások, többmonitoros konfiguráció). • Az asztal zárolva van, vagy a felhasználó kijelentkezett. • Az egyidejű kapcsolatok száma meghaladta az eszköz által támogatott számot. |
|
| PointerCaptureLost | Ez akkor fordul elő, ha egy másik felhasználói felületi elem rögzíti az egérmutatót, a mutató ki lett engedve, vagy egy másik mutató programozott módon lett rögzítve. Megjegyzés: Nincs megfelelő mutatórögzítési esemény. |
|
| PointerEntered | Akkor fordul elő, ha egy mutató belép egy elem határoló területébe. Az érintéses, érintőpárnás, egérrel és tollal történő bevitel mind kissé különböző módon történhet. • Az érintés esemény aktiválásához ujjal való érintés szükséges, vagy közvetlenül az elem megérintésével, vagy az elem határoló területére való mozgással. • Az egér és az érintőpárnán is van egy képernyő-kurzor, amely mindig látható, és akkor is aktiválja ezt az eseményt, ha nincs egér vagy érintőpad gomb lenyomva. • Az érintéshez hasonlóan a toll is közvetlenül aktiválja ezt az eseményt azzal, hogy leérint az elemre vagy belép az elem határoló területére. A tollnak van azonban egy lebegő állapota (IsInRange), amely, ha igaz, aktiválja ezt az eseményt. |
|
| PointerExited | Akkor fordul elő, ha egy mutató elhagyja az elem határoló területét. Az érintéses, érintőpárnás, egérrel és tollal történő bevitel mind kissé különböző módon történhet. • Az érintéshez ujjal kell érintkezni, és aktiválni kell ezt az eseményt, amikor a mutató kimozdul az elem határoló területéről. • Az egér és az érintőpárnán is van egy képernyő-kurzor, amely mindig látható, és akkor is aktiválja ezt az eseményt, ha nincs egér vagy érintőpad gomb lenyomva. • Az érintéshez hasonlóan a toll is aktiválja ezt az eseményt, amikor kimozdul az elem határoló területéről. A tollnak van egy lebegési állapota (IsInRange) is, amely akkor váltja ki ezt az eseményt, amikor az állapot igazról hamisra változik. |
|
| PointerMoved | Akkor fordul elő, ha egy mutató koordinátákat, gombállapotot, nyomást, dőlést vagy érintkezési geometriát (például szélességet és magasságot) módosít egy elem határoló területén. Az érintéses, érintőpárnás, egérrel és tollal történő bevitel mind kissé különböző módon történhet. • Az érintéshez ujjal kell érintkezni, és ezt az eseményt csak akkor aktiválja, ha az elem határoló területén belül érintkezik. • Az egér és az érintőpárnán is van egy képernyő-kurzor, amely mindig látható, és akkor is aktiválja ezt az eseményt, ha nincs egér vagy érintőpad gomb lenyomva. • Az érintéshez hasonlóan a toll is aktiválja ezt az eseményt, ha az elem határoló területén belül érintkezik. A tollnak azonban van egy rámutatási állapota is (IsInRange), amely, ha igaz és az elem határoló területén belül van, kiváltja ezt az eseményt. |
|
| Mutató megnyomva | Akkor fordul elő, ha a mutató nyomási műveletet jelez (például érintés, egérgomb lenyomása, tolllenyomás vagy érintőpad gomb lenyomása) az elem határoló területén. A CapturePointert az esemény kezelőjének kell meghívnia. |
|
| PointerReleased | Akkor fordul elő, ha az egérmutató egy felengedési műveletet jelez (például érintés felengedése, egérgomb felengedése, toll felengedése vagy érintőpárna gomb engedése) az elem határoló területén belül, vagy ha a mutató rögzítve van, a határoló területen kívül. | |
| MutatókerékVáltozott | Az egérkerék elforgatásakor fordul elő. Az egér bemenete egyetlen, az egér bemenetének észlelésekor hozzárendelt mutatóhoz van társítva. Az egérgombra (balra, kerékre vagy jobbra) kattintva másodlagos társítás jön létre a mutató és a gomb között a PointerMoved eseményen keresztül. |
Példa mutatóeseményre
Íme néhány kódrészlet egy alapszintű mutatókövető alkalmazásból, amely bemutatja, hogyan figyelhet és kezelhet eseményeket több mutató esetében, és hogyan szerezheti be a társított mutatók különböző tulajdonságait.
A minta letöltése Pointer bemeneti mintából (alapszintű)
A felhasználói felület létrehozása
Ebben a példában egy téglalapot (Target) használunk, mint az objektum, amely a mutató bemenetét fogadja. A cél színe megváltozik, amikor a mutató állapota megváltozik.
Az egyes egérmutatók részletei egy lebegő TextBlock-ban jelennek meg, amely az egérmutatót követi mozgáskor. Maguk a mutatóesemények a téglalaptól jobbra lévő RichTextBlockban jelennek meg.
A felhasználói felülethez a következő XAML-t (Extensible Application Markup Language) használjuk ebben a példában.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="250"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="320" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Canvas Name="Container"
Grid.Column="0"
Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="245,0"
Height="320" Width="640">
<Rectangle Name="Target"
Fill="#FF0000"
Stroke="Black"
StrokeThickness="0"
Height="320" Width="640" />
</Canvas>
<Grid Grid.Column="1" Grid.Row="0" Grid.RowSpan="3">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Name="buttonClear"
Grid.Row="0"
Content="Clear"
Foreground="White"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
</Button>
<ScrollViewer Name="eventLogScrollViewer" Grid.Row="1"
VerticalScrollMode="Auto"
Background="Black">
<RichTextBlock Name="eventLog"
TextWrapping="Wrap"
Foreground="#FFFFFF"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Grid.ColumnSpan="2">
</RichTextBlock>
</ScrollViewer>
</Grid>
</Grid>
Mutatóesemények figyelése
A legtöbb esetben azt javasoljuk, hogy az eseménykezelő PointerRoutedEventArgsén keresztül kapja meg a mutató adatait.
Ha az eseményargumentum nem teszi elérhetővé a szükséges mutatóadatokat, hozzáférhet a kiterjesztett PointerPoint információkhoz, amelyeket a GetCurrentPoint és GetIntermediatePoints metódusai által elérhetőek a PointerRoutedEventArgs.
Az alábbi kód beállítja a globális szótárobjektumot az egyes aktív mutatók nyomon követéséhez, és azonosítja a célobjektum különböző mutatóesemény-figyelőit.
// Dictionary to maintain information about each active pointer.
// An entry is added during PointerPressed/PointerEntered events and removed
// during PointerReleased/PointerCaptureLost/PointerCanceled/PointerExited events.
Dictionary<uint, Windows.UI.Xaml.Input.Pointer> pointers;
public MainPage()
{
this.InitializeComponent();
// Initialize the dictionary.
pointers = new Dictionary<uint, Windows.UI.Xaml.Input.Pointer>();
// Declare the pointer event handlers.
Target.PointerPressed +=
new PointerEventHandler(Target_PointerPressed);
Target.PointerEntered +=
new PointerEventHandler(Target_PointerEntered);
Target.PointerReleased +=
new PointerEventHandler(Target_PointerReleased);
Target.PointerExited +=
new PointerEventHandler(Target_PointerExited);
Target.PointerCanceled +=
new PointerEventHandler(Target_PointerCanceled);
Target.PointerCaptureLost +=
new PointerEventHandler(Target_PointerCaptureLost);
Target.PointerMoved +=
new PointerEventHandler(Target_PointerMoved);
Target.PointerWheelChanged +=
new PointerEventHandler(Target_PointerWheelChanged);
buttonClear.Click +=
new RoutedEventHandler(ButtonClear_Click);
}
Mutatóesemények kezelése
Ezután felhasználói felületi visszajelzést használunk az alapvető mutatóesemény-kezelők bemutatásához.
Ez a kezelő kezeli a PointerPressed eseményt. Hozzáadjuk az eseményt az eseménynaplóhoz, hozzáadjuk az egérmutatót az aktív mutatószótárhoz, és megjelenítjük a mutató részleteit.
Megjegyzés:
A PointerPressed és a PointerReleased események nem mindig fordulnak elő párokban. Az alkalmazásnak figyelnie kell és kezelnie kell minden olyan eseményt, amely lefelé mutatót eredményezhet (például PointerExited, PointerCanceled és PointerCaptureLost).
/// <summary>
/// The pointer pressed event handler.
/// PointerPressed and PointerReleased don't always occur in pairs.
/// Your app should listen for and handle any event that can conclude
/// a pointer down (PointerExited, PointerCanceled, PointerCaptureLost).
/// </summary>
/// <param name="sender">Source of the pointer event.</param>
/// <param name="e">Event args for the pointer routed event.</param>
void Target_PointerPressed(object sender, PointerRoutedEventArgs e)
{
// Prevent most handlers along the event route from handling the same event again.
e.Handled = true;
PointerPoint ptrPt = e.GetCurrentPoint(Target);
// Update event log.
UpdateEventLog("Down: " + ptrPt.PointerId);
// Lock the pointer to the target.
Target.CapturePointer(e.Pointer);
// Update event log.
UpdateEventLog("Pointer captured: " + ptrPt.PointerId);
// Check if pointer exists in dictionary (ie, enter occurred prior to press).
if (!pointers.ContainsKey(ptrPt.PointerId))
{
// Add contact to dictionary.
pointers[ptrPt.PointerId] = e.Pointer;
}
// Change background color of target when pointer contact detected.
Target.Fill = new SolidColorBrush(Windows.UI.Colors.Green);
// Display pointer details.
CreateInfoPop(ptrPt);
}
- Ez a kezelő kezeli a PointerEntered eseményt . Hozzáadjuk az eseményt az eseménynaplóhoz, hozzáadjuk az egérmutatót a mutatógyűjteményhez, és megjelenítjük a mutató részleteit.
/// <summary>
/// The pointer entered event handler.
/// We do not capture the pointer on this event.
/// </summary>
/// <param name="sender">Source of the pointer event.</param>
/// <param name="e">Event args for the pointer routed event.</param>
private void Target_PointerEntered(object sender, PointerRoutedEventArgs e)
{
// Prevent most handlers along the event route from handling the same event again.
e.Handled = true;
PointerPoint ptrPt = e.GetCurrentPoint(Target);
// Update event log.
UpdateEventLog("Entered: " + ptrPt.PointerId);
// Check if pointer already exists (if enter occurred prior to down).
if (!pointers.ContainsKey(ptrPt.PointerId))
{
// Add contact to dictionary.
pointers[ptrPt.PointerId] = e.Pointer;
}
if (pointers.Count == 0)
{
// Change background color of target when pointer contact detected.
Target.Fill = new SolidColorBrush(Windows.UI.Colors.Blue);
}
// Display pointer details.
CreateInfoPop(ptrPt);
}
Ez a kezelő kezeli a PointerMoved eseményt . Hozzáadjuk az eseményt az eseménynaplóhoz, és frissítjük a mutató részleteit.
Fontos
Az egér bemenete egyetlen, az egér bemenetének észlelésekor hozzárendelt mutatóhoz van társítva. Az egérgomb (bal, kerék vagy jobb) kattintásával másodlagos kapcsolat jön létre a mutató és a gomb között a PointerPressed eseményen keresztül. A PointerReleased esemény csak akkor aktiválódik, ha ugyanaz az egérgomb ki van adva (az esemény befejezéséig nem lehet más gombot társítani a mutatóhoz). A kizárólagos társítás miatt a többi egérgomb-kattintás át lesz irányítva a PointerMoved eseményen.
/// <summary>
/// The pointer moved event handler.
/// </summary>
/// <param name="sender">Source of the pointer event.</param>
/// <param name="e">Event args for the pointer routed event.</param>
private void Target_PointerMoved(object sender, PointerRoutedEventArgs e)
{
// Prevent most handlers along the event route from handling the same event again.
e.Handled = true;
PointerPoint ptrPt = e.GetCurrentPoint(Target);
// Multiple, simultaneous mouse button inputs are processed here.
// Mouse input is associated with a single pointer assigned when
// mouse input is first detected.
// Clicking additional mouse buttons (left, wheel, or right) during
// the interaction creates secondary associations between those buttons
// and the pointer through the pointer pressed event.
// The pointer released event is fired only when the last mouse button
// associated with the interaction (not necessarily the initial button)
// is released.
// Because of this exclusive association, other mouse button clicks are
// routed through the pointer move event.
if (ptrPt.PointerDevice.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Mouse)
{
if (ptrPt.Properties.IsLeftButtonPressed)
{
UpdateEventLog("Left button: " + ptrPt.PointerId);
}
if (ptrPt.Properties.IsMiddleButtonPressed)
{
UpdateEventLog("Wheel button: " + ptrPt.PointerId);
}
if (ptrPt.Properties.IsRightButtonPressed)
{
UpdateEventLog("Right button: " + ptrPt.PointerId);
}
}
// Display pointer details.
UpdateInfoPop(ptrPt);
}
- Ez a kezelő kezeli a PointerWheelChanged eseményt . Hozzáadjuk az eseményt az eseménynaplóhoz, hozzáadjuk a mutatót a mutatótömbhöz (ha szükséges), és megjelenítjük a mutató részleteit.
/// <summary>
/// The pointer wheel event handler.
/// </summary>
/// <param name="sender">Source of the pointer event.</param>
/// <param name="e">Event args for the pointer routed event.</param>
private void Target_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
{
// Prevent most handlers along the event route from handling the same event again.
e.Handled = true;
PointerPoint ptrPt = e.GetCurrentPoint(Target);
// Update event log.
UpdateEventLog("Mouse wheel: " + ptrPt.PointerId);
// Check if pointer already exists (for example, enter occurred prior to wheel).
if (!pointers.ContainsKey(ptrPt.PointerId))
{
// Add contact to dictionary.
pointers[ptrPt.PointerId] = e.Pointer;
}
// Display pointer details.
CreateInfoPop(ptrPt);
}
- Ez a kezelő kezeli a PointerReleased eseményt , ahol a digitalizálóval való kapcsolat megszakad. Hozzáadjuk az eseményt az eseménynaplóhoz, eltávolítjuk a mutatót a mutatógyűjteményből, és frissítjük a mutató részleteit.
/// <summary>
/// The pointer released event handler.
/// PointerPressed and PointerReleased don't always occur in pairs.
/// Your app should listen for and handle any event that can conclude
/// a pointer down (PointerExited, PointerCanceled, PointerCaptureLost).
/// </summary>
/// <param name="sender">Source of the pointer event.</param>
/// <param name="e">Event args for the pointer routed event.</param>
void Target_PointerReleased(object sender, PointerRoutedEventArgs e)
{
// Prevent most handlers along the event route from handling the same event again.
e.Handled = true;
PointerPoint ptrPt = e.GetCurrentPoint(Target);
// Update event log.
UpdateEventLog("Up: " + ptrPt.PointerId);
// If event source is mouse or touchpad and the pointer is still
// over the target, retain pointer and pointer details.
// Return without removing pointer from pointers dictionary.
// For this example, we assume a maximum of one mouse pointer.
if (ptrPt.PointerDevice.PointerDeviceType != Windows.Devices.Input.PointerDeviceType.Mouse)
{
// Update target UI.
Target.Fill = new SolidColorBrush(Windows.UI.Colors.Red);
DestroyInfoPop(ptrPt);
// Remove contact from dictionary.
if (pointers.ContainsKey(ptrPt.PointerId))
{
pointers[ptrPt.PointerId] = null;
pointers.Remove(ptrPt.PointerId);
}
// Release the pointer from the target.
Target.ReleasePointerCapture(e.Pointer);
// Update event log.
UpdateEventLog("Pointer released: " + ptrPt.PointerId);
}
else
{
Target.Fill = new SolidColorBrush(Windows.UI.Colors.Blue);
}
}
- Ez a kezelő kezeli a PointerExited eseményt (ha a digitalizálóval tart kapcsolatot). Hozzáadjuk az eseményt az eseménynaplóhoz, eltávolítjuk az egérmutatót a mutatótömbből, és frissítjük a mutató részleteit.
/// <summary>
/// The pointer exited event handler.
/// </summary>
/// <param name="sender">Source of the pointer event.</param>
/// <param name="e">Event args for the pointer routed event.</param>
private void Target_PointerExited(object sender, PointerRoutedEventArgs e)
{
// Prevent most handlers along the event route from handling the same event again.
e.Handled = true;
PointerPoint ptrPt = e.GetCurrentPoint(Target);
// Update event log.
UpdateEventLog("Pointer exited: " + ptrPt.PointerId);
// Remove contact from dictionary.
if (pointers.ContainsKey(ptrPt.PointerId))
{
pointers[ptrPt.PointerId] = null;
pointers.Remove(ptrPt.PointerId);
}
if (pointers.Count == 0)
{
Target.Fill = new SolidColorBrush(Windows.UI.Colors.Red);
}
// Update the UI and pointer details.
DestroyInfoPop(ptrPt);
}
- Ez a kezelő kezeli a PointerCanceled eseményt . Hozzáadjuk az eseményt az eseménynaplóhoz, eltávolítjuk az egérmutatót a mutatótömbből, és frissítjük a mutató részleteit.
/// <summary>
/// The pointer canceled event handler.
/// Fires for various reasons, including:
/// - Touch contact canceled by pen coming into range of the surface.
/// - The device doesn't report an active contact for more than 100ms.
/// - The desktop is locked or the user logged off.
/// - The number of simultaneous contacts exceeded the number supported by the device.
/// </summary>
/// <param name="sender">Source of the pointer event.</param>
/// <param name="e">Event args for the pointer routed event.</param>
private void Target_PointerCanceled(object sender, PointerRoutedEventArgs e)
{
// Prevent most handlers along the event route from handling the same event again.
e.Handled = true;
PointerPoint ptrPt = e.GetCurrentPoint(Target);
// Update event log.
UpdateEventLog("Pointer canceled: " + ptrPt.PointerId);
// Remove contact from dictionary.
if (pointers.ContainsKey(ptrPt.PointerId))
{
pointers[ptrPt.PointerId] = null;
pointers.Remove(ptrPt.PointerId);
}
if (pointers.Count == 0)
{
Target.Fill = new SolidColorBrush(Windows.UI.Colors.Black);
}
DestroyInfoPop(ptrPt);
}
Ez a kezelő kezeli a PointerCaptureLost eseményt . Hozzáadjuk az eseményt az eseménynaplóhoz, eltávolítjuk az egérmutatót a mutatótömbből, és frissítjük a mutató részleteit.
Megjegyzés:
A PointerCaptureLost előfordulhat a PointerReleased helyett. A mutatórögzítés számos okból elveszhet, például a felhasználói beavatkozás, egy másik mutató programozott rögzítése és a PointerReleased meghívása miatt.
/// <summary>
/// The pointer capture lost event handler.
/// Fires for various reasons, including:
/// - User interactions
/// - Programmatic capture of another pointer
/// - Captured pointer was deliberately released
// PointerCaptureLost can fire instead of PointerReleased.
/// </summary>
/// <param name="sender">Source of the pointer event.</param>
/// <param name="e">Event args for the pointer routed event.</param>
private void Target_PointerCaptureLost(object sender, PointerRoutedEventArgs e)
{
// Prevent most handlers along the event route from handling the same event again.
e.Handled = true;
PointerPoint ptrPt = e.GetCurrentPoint(Target);
// Update event log.
UpdateEventLog("Pointer capture lost: " + ptrPt.PointerId);
if (pointers.Count == 0)
{
Target.Fill = new SolidColorBrush(Windows.UI.Colors.Black);
}
// Remove contact from dictionary.
if (pointers.ContainsKey(ptrPt.PointerId))
{
pointers[ptrPt.PointerId] = null;
pointers.Remove(ptrPt.PointerId);
}
DestroyInfoPop(ptrPt);
}
Mutató tulajdonságainak lekérése
Ahogy korábban említettem, a PointerRoutedEventArgsGetCurrentPoint és GetIntermediatePoints metódusával beszerzett Windows.UI.Input.PointerPoint objektumból kell lekérnie a legtöbb kiterjesztett mutatóadatokat. Az alábbi kódrészletek bemutatják, hogyan.
- Először minden egyes mutatóhoz létrehozunk egy új TextBlock-et .
/// <summary>
/// Create the pointer info popup.
/// </summary>
/// <param name="ptrPt">Reference to the input pointer.</param>
void CreateInfoPop(PointerPoint ptrPt)
{
TextBlock pointerDetails = new TextBlock();
pointerDetails.Name = ptrPt.PointerId.ToString();
pointerDetails.Foreground = new SolidColorBrush(Windows.UI.Colors.White);
pointerDetails.Text = QueryPointer(ptrPt);
TranslateTransform x = new TranslateTransform();
x.X = ptrPt.Position.X + 20;
x.Y = ptrPt.Position.Y + 20;
pointerDetails.RenderTransform = x;
Container.Children.Add(pointerDetails);
}
- Ezután biztosítjuk a mutató adatainak frissítését a mutatóhoz társított meglévő TextBlockban .
/// <summary>
/// Update the pointer info popup.
/// </summary>
/// <param name="ptrPt">Reference to the input pointer.</param>
void UpdateInfoPop(PointerPoint ptrPt)
{
foreach (var pointerDetails in Container.Children)
{
if (pointerDetails.GetType().ToString() == "Windows.UI.Xaml.Controls.TextBlock")
{
TextBlock textBlock = (TextBlock)pointerDetails;
if (textBlock.Name == ptrPt.PointerId.ToString())
{
// To get pointer location details, we need extended pointer info.
// We get the pointer info through the getCurrentPoint method
// of the event argument.
TranslateTransform x = new TranslateTransform();
x.X = ptrPt.Position.X + 20;
x.Y = ptrPt.Position.Y + 20;
pointerDetails.RenderTransform = x;
textBlock.Text = QueryPointer(ptrPt);
}
}
}
}
- Végül lekérdezzük a különböző mutatótulajdonságokat.
/// <summary>
/// Get pointer details.
/// </summary>
/// <param name="ptrPt">Reference to the input pointer.</param>
/// <returns>A string composed of pointer details.</returns>
String QueryPointer(PointerPoint ptrPt)
{
String details = "";
switch (ptrPt.PointerDevice.PointerDeviceType)
{
case Windows.Devices.Input.PointerDeviceType.Mouse:
details += "\nPointer type: mouse";
break;
case Windows.Devices.Input.PointerDeviceType.Pen:
details += "\nPointer type: pen";
if (ptrPt.IsInContact)
{
details += "\nPressure: " + ptrPt.Properties.Pressure;
details += "\nrotation: " + ptrPt.Properties.Orientation;
details += "\nTilt X: " + ptrPt.Properties.XTilt;
details += "\nTilt Y: " + ptrPt.Properties.YTilt;
details += "\nBarrel button pressed: " + ptrPt.Properties.IsBarrelButtonPressed;
}
break;
case Windows.Devices.Input.PointerDeviceType.Touch:
details += "\nPointer type: touch";
details += "\nrotation: " + ptrPt.Properties.Orientation;
details += "\nTilt X: " + ptrPt.Properties.XTilt;
details += "\nTilt Y: " + ptrPt.Properties.YTilt;
break;
default:
details += "\nPointer type: n/a";
break;
}
GeneralTransform gt = Target.TransformToVisual(this);
Point screenPoint;
screenPoint = gt.TransformPoint(new Point(ptrPt.Position.X, ptrPt.Position.Y));
details += "\nPointer Id: " + ptrPt.PointerId.ToString() +
"\nPointer location (target): " + Math.Round(ptrPt.Position.X) + ", " + Math.Round(ptrPt.Position.Y) +
"\nPointer location (container): " + Math.Round(screenPoint.X) + ", " + Math.Round(screenPoint.Y);
return details;
}
Elsődleges mutató
Egyes beviteli eszközök, például az érintődigitalizáló vagy az érintőpad többet támogatnak, mint az egér vagy toll tipikus egyetlen mutatója (a legtöbb esetben, mivel a Surface Hub két tollbemenetet támogat).
A PointerPointerProperties osztály írásvédett IsPrimary tulajdonságával azonosíthat és különböztethet meg egyetlen elsődleges mutatót (az elsődleges mutató mindig az első mutató, amelyet egy bemeneti sorozat során észleltek).
Az elsődleges mutató azonosításával emulálhatja az egér- vagy tollbemenetet, testre szabhatja az interakciókat, vagy más konkrét funkciókat vagy felhasználói felületet biztosíthat.
Megjegyzés:
Ha az elsődleges mutató ki van adva, megszakítva vagy elveszik egy bemeneti sorozat során, a rendszer nem hoz létre elsődleges bemeneti mutatót, amíg új bemeneti sorozat nem indul el (a bemeneti sorozat akkor fejeződik be, amikor az összes mutatót elengedték, megszakították vagy elveszítették).
Példa elsődleges mutató animációra
Ezek a kódrészletek bemutatják, hogyan adhat speciális vizuális visszajelzést, hogy a felhasználó különbséget tegyen a mutató bemenetei között az alkalmazásban.
Ez az alkalmazás színt és animációt is használ az elsődleges mutató kiemeléséhez.
A minta letöltése Pointer bemeneti mintából (UserControl animációval)
Vizuális visszajelzés
Egy UserControlt határozunk meg, amely egy XAML Ellipse objektumon alapul, kiemeli, hogy az egyes mutatók hol találhatók a vásznon, és egy Storyboard segítségével animálja az elsődleges mutatónak megfelelő ellipszist.
Az XAML a következő:
<UserControl
x:Class="UWP_Pointers.PointerEllipse"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWP_Pointers"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="100"
d:DesignWidth="100">
<UserControl.Resources>
<Style x:Key="EllipseStyle" TargetType="Ellipse">
<Setter Property="Transitions">
<Setter.Value>
<TransitionCollection>
<ContentThemeTransition/>
</TransitionCollection>
</Setter.Value>
</Setter>
</Style>
<Storyboard x:Name="myStoryboard">
<!-- Animates the value of a Double property between
two target values using linear interpolation over the
specified Duration. -->
<DoubleAnimation
Storyboard.TargetName="ellipse"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleY)"
Duration="0:0:1"
AutoReverse="True"
RepeatBehavior="Forever" From="1.0" To="1.4">
</DoubleAnimation>
<!-- Animates the value of a Double property between
two target values using linear interpolation over the
specified Duration. -->
<DoubleAnimation
Storyboard.TargetName="ellipse"
Storyboard.TargetProperty="(RenderTransform).(ScaleTransform.ScaleX)"
Duration="0:0:1"
AutoReverse="True"
RepeatBehavior="Forever" From="1.0" To="1.4">
</DoubleAnimation>
<!-- Animates the value of a Color property between
two target values using linear interpolation over the
specified Duration. -->
<ColorAnimation
Storyboard.TargetName="ellipse"
EnableDependentAnimation="True"
Storyboard.TargetProperty="(Fill).(SolidColorBrush.Color)"
From="White" To="Red" Duration="0:0:1"
AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</UserControl.Resources>
<Grid x:Name="CompositionContainer">
<Ellipse Name="ellipse"
StrokeThickness="2"
Width="{x:Bind Diameter}"
Height="{x:Bind Diameter}"
Style="{StaticResource EllipseStyle}" />
</Grid>
</UserControl>
És itt van a kód mögött:
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
// The User Control item template is documented at
// https://go.microsoft.com/fwlink/?LinkId=234236
namespace UWP_Pointers
{
/// <summary>
/// Pointer feedback object.
/// </summary>
public sealed partial class PointerEllipse : UserControl
{
// Reference to the application canvas.
Canvas canvas;
/// <summary>
/// Ellipse UI for pointer feedback.
/// </summary>
/// <param name="c">The drawing canvas.</param>
public PointerEllipse(Canvas c)
{
this.InitializeComponent();
canvas = c;
}
/// <summary>
/// Gets or sets the pointer Id to associate with the PointerEllipse object.
/// </summary>
public uint PointerId
{
get { return (uint)GetValue(PointerIdProperty); }
set { SetValue(PointerIdProperty, value); }
}
// Using a DependencyProperty as the backing store for PointerId.
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty PointerIdProperty =
DependencyProperty.Register("PointerId", typeof(uint),
typeof(PointerEllipse), new PropertyMetadata(null));
/// <summary>
/// Gets or sets whether the associated pointer is Primary.
/// </summary>
public bool PrimaryPointer
{
get { return (bool)GetValue(PrimaryPointerProperty); }
set
{
SetValue(PrimaryPointerProperty, value);
}
}
// Using a DependencyProperty as the backing store for PrimaryPointer.
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty PrimaryPointerProperty =
DependencyProperty.Register("PrimaryPointer", typeof(bool),
typeof(PointerEllipse), new PropertyMetadata(false));
/// <summary>
/// Gets or sets the ellipse style based on whether the pointer is Primary.
/// </summary>
public bool PrimaryEllipse
{
get { return (bool)GetValue(PrimaryEllipseProperty); }
set
{
SetValue(PrimaryEllipseProperty, value);
if (value)
{
SolidColorBrush fillBrush =
(SolidColorBrush)Application.Current.Resources["PrimaryFillBrush"];
SolidColorBrush strokeBrush =
(SolidColorBrush)Application.Current.Resources["PrimaryStrokeBrush"];
ellipse.Fill = fillBrush;
ellipse.Stroke = strokeBrush;
ellipse.RenderTransform = new CompositeTransform();
ellipse.RenderTransformOrigin = new Point(.5, .5);
myStoryboard.Begin();
}
else
{
SolidColorBrush fillBrush =
(SolidColorBrush)Application.Current.Resources["SecondaryFillBrush"];
SolidColorBrush strokeBrush =
(SolidColorBrush)Application.Current.Resources["SecondaryStrokeBrush"];
ellipse.Fill = fillBrush;
ellipse.Stroke = strokeBrush;
}
}
}
// Using a DependencyProperty as the backing store for PrimaryEllipse.
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty PrimaryEllipseProperty =
DependencyProperty.Register("PrimaryEllipse",
typeof(bool), typeof(PointerEllipse), new PropertyMetadata(false));
/// <summary>
/// Gets or sets the diameter of the PointerEllipse object.
/// </summary>
public int Diameter
{
get { return (int)GetValue(DiameterProperty); }
set { SetValue(DiameterProperty, value); }
}
// Using a DependencyProperty as the backing store for Diameter. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DiameterProperty =
DependencyProperty.Register("Diameter", typeof(int),
typeof(PointerEllipse), new PropertyMetadata(120));
}
}
A felhasználói felület létrehozása
A példában szereplő felhasználói felület a bemeneti vászonra korlátozódik, ahol nyomon követjük a mutatókat, és megjelenítjük a mutatójelzőket és az elsődleges mutatóanimációt (ha van), valamint egy fejlécsávot, amely egy mutatószámlálót és egy elsődleges mutatóazonosítót tartalmaz.
Itt található a MainPage.xaml:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="HeaderPanel"
Orientation="Horizontal"
Grid.Row="0">
<StackPanel.Transitions>
<TransitionCollection>
<AddDeleteThemeTransition/>
</TransitionCollection>
</StackPanel.Transitions>
<TextBlock x:Name="Header"
Text="Basic pointer tracking sample - IsPrimary"
Style="{ThemeResource HeaderTextBlockStyle}"
Margin="10,0,0,0" />
<TextBlock x:Name="PointerCounterLabel"
VerticalAlignment="Center"
Style="{ThemeResource BodyTextBlockStyle}"
Text="Number of pointers: "
Margin="50,0,0,0"/>
<TextBlock x:Name="PointerCounter"
VerticalAlignment="Center"
Style="{ThemeResource BodyTextBlockStyle}"
Text="0"
Margin="10,0,0,0"/>
<TextBlock x:Name="PointerPrimaryLabel"
VerticalAlignment="Center"
Style="{ThemeResource BodyTextBlockStyle}"
Text="Primary: "
Margin="50,0,0,0"/>
<TextBlock x:Name="PointerPrimary"
VerticalAlignment="Center"
Style="{ThemeResource BodyTextBlockStyle}"
Text="n/a"
Margin="10,0,0,0"/>
</StackPanel>
<Grid Grid.Row="1">
<!--The canvas where we render the pointer UI.-->
<Canvas x:Name="pointerCanvas"/>
</Grid>
</Grid>
Mutatóesemények kezelése
Végül meghatározzuk az alapvető mutatóesemény-kezelőket a mögöttes MainPage.xaml.cs kódban. Itt nem fogjuk reprodukálni a kódot, mivel az előző példában az alapokat tárgyaltuk, de a munkamintát letöltheti Pointer bemeneti mintából (UserControl animációval).
Kapcsolódó cikkek
Témakörminták
Egyéb minták
- Alap bemeneti minta
- Alacsony késleltetésű bemeneti minta
- Felhasználói interakciós mód mintája
- Fókusz vizuális mintája
Archív minták
Windows developer