Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Surface Pen (finns att köpa i Microsoft Store).
Översikt
Optimera Din Windows-app för penninmatning för att tillhandahålla både standardfunktioner för pekareenheter och den bästa Windows Ink-upplevelsen för dina användare.
Anmärkning
Det här avsnittet fokuserar på Windows Ink-plattformen. Allmän hantering av pekarindata (liknar mus, touch och pekplatta) finns i Hantera pekarindata.
Använda pennanteckning i din Windows-app
Använda Windows Pen and Ink för att skapa mer engagerande företagsappar
Windows Ink-plattformen, tillsammans med en pennenhet, är ett naturligt sätt att skapa digitala handskrivna anteckningar, ritningar och anteckningar. Plattformen stöder insamling av digitaliserarens indata som bläckdata, genererar bläckdata, hanterar bläckdata, återger bläckdata som pennstreck på utdataenhet och konverterar bläck till text via handskriftsigenkänning.
Förutom att fånga pennans grundläggande position och rörelse när användaren skriver eller ritar, kan din app också spåra och samla in de varierande mängder tryck som används under en stroke. Med den här informationen, tillsammans med inställningar för pennspetsform, storlek och rotation, pennanteckningsfärg och syfte (oformaterad penna, radering, markering och val), kan du tillhandahålla användarupplevelser som liknar att skriva eller rita på papper med penna, penna eller pensel.
Anmärkning
Din app kan också ha stöd för bläckinmatning från andra pekdon, inklusive touch-digitaliserare och musenheter.
Bläckplattformen är mycket flexibel. Den är utformad för att stödja olika funktionalitetsnivåer, beroende på dina krav.
Riktlinjer för Windows Ink UX finns i kontroller för pennanteckning.
Komponenter i Windows Ink-plattformen
Komponent | Beskrivning |
---|---|
InkCanvas | En XAML UI-plattformskontroll som som standard tar emot och visar alla indata från en penna som antingen ett pennstreck eller ett raderingsdrag. Mer information om hur du använder InkCanvas finns i Recognize Windows Ink strokes as text och Store and retrieve Windows Ink stroke data. |
InkPresenter | Ett code-behind-objekt, instansierat tillsammans med ett InkCanvas kontrollelement (som exponeras via egenskapen InkCanvas.InkPresenter). Det här objektet innehåller alla standardfunktioner för bläckning som exponeras av InkCanvas, tillsammans med en omfattande uppsättning API:er för ytterligare anpassning och personalisering. Mer information om hur du använder InkPresenter finns i Identifiera Windows-pennstreck som text och Lagra och hämta Windows Ink-linjedata. |
Bläckverktygsfält | En XAML UI-plattformskontroll som innehåller en anpassningsbar och utökningsbar samling knappar som aktiverar pennanteckningsrelaterade funktioner i en associerad InkCanvas. Mer information om hur du använder InkToolbar finns i Lägg till en InkToolbar i en inking-app för Windows. |
IInkD2DRenderer | Aktiverar återgivning av pennstreck till den angivna Direct2D-enhetskontexten för en Universal Windows-app istället för standardkontrollen InkCanvas. Detta möjliggör fullständig anpassning av pennanteckningsupplevelsen. Mer information finns i bläckprovet för -komplexet. |
Grundläggande pennanteckning med InkCanvas
Om du vill lägga till grundläggande pennanteckningsfunktioner placerar du bara en InkCanvas UWP-plattformskontroll på rätt sida i din app.
Som standard stöder InkCanvas endast bläckinmatning med penna. Indata återges antingen som en bläcklinje med standardinställningar för färg och tjocklek (en svart kulspetspenna med en tjocklek på 2 bildpunkter) eller behandlas som ett raderingsverktyg (när indata kommer från en suddgummispets eller när pennspetsen är ändrad med en raderingsknapp).
Anmärkning
Om ett radergummitips eller knapp inte finns kan InkCanvas konfigureras för att bearbeta indata från pennspetsen som ett raderingsdrag.
I det här exemplet lägger en InkCanvas över en bakgrundsbild.
Anmärkning
En InkCanvas har standardegenskaperna Höjd och Bredd på noll, såvida det inte är underordnat till ett element som automatiskt storleksanpassar sina underordnade element, till exempel StackPanel - eller Grid-kontroller .
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0">
<TextBlock x:Name="Header"
Text="Basic ink sample"
Style="{ThemeResource HeaderTextBlockStyle}"
Margin="10,0,0,0" />
</StackPanel>
<Grid Grid.Row="1">
<Image Source="Assets\StoreLogo.png" />
<InkCanvas x:Name="inkCanvas" />
</Grid>
</Grid>
Den här serien med bilder visar hur pennindata återges av den här InkCanvas kontrollkomponent.
![]() |
![]() |
![]() |
---|---|---|
Den tomma InkCanvas med en bakgrundsbild. | InkCanvas med pennstreck. | InkCanvas med en funktion där hela penseldrag raderas (notera att radera opererar på ett helt penseldrag, inte en del). |
Pennanteckningsfunktionen som stöds av InkCanvas-kontrollen tillhandahålls av ett bakomliggande kod-objekt som kallas InkPresenter.
För grundläggande bläckteckning behöver du inte oroa dig för InkPresenter. Men om du vill anpassa och konfigurera pennanteckningsbeteende på InkCanvas måste du komma åt motsvarande InkPresenter-objekt .
Grundläggande anpassning med InkPresenter
Ett InkPresenter- objekt instansieras med varje InkCanvas kontroll.
Anmärkning
InkPresenter kan inte instansieras direkt. Den nås istället via egenskapen InkPresenter för InkCanvas.
Tillsammans med att tillhandahålla alla standardinmatningsbeteenden för motsvarande InkCanvas kontroll, tillhandahåller InkPresenter en omfattande uppsättning API:er för ytterligare anpassning av linjer och finkornig hantering av pennindata (standard och ändrad). Detta omfattar strokeegenskaper, enhetstyper som stöds och huruvida indata bearbetas av objektet eller skickas till appen för bearbetning.
Anmärkning
Standard bläckinmatning (från pennspets eller suddgummi) modifieras inte med ett sekundärt maskinvarutillbehör, såsom en penntubknapp, höger musknapp eller liknande mekanism.
Som standard stöds bläck endast för penninmatning. Här konfigurerar vi InkPresenter för att tolka indata från både penna och mus som pennstreck. Vi anger även några initiala bläckstrecksattribut som används för att återge streck på InkCanvas.
Om du vill aktivera mus- och pekinmatning anger du egenskapen InputDeviceTypes för InkPresenter till den kombination av CoreInputDeviceTypes-värden som du vill använda.
public MainPage()
{
this.InitializeComponent();
// Set supported inking device types.
inkCanvas.InkPresenter.InputDeviceTypes =
Windows.UI.Core.CoreInputDeviceTypes.Mouse |
Windows.UI.Core.CoreInputDeviceTypes.Pen;
// Set initial ink stroke attributes.
InkDrawingAttributes drawingAttributes = new InkDrawingAttributes();
drawingAttributes.Color = Windows.UI.Colors.Black;
drawingAttributes.IgnorePressure = false;
drawingAttributes.FitToCurve = true;
inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes);
}
Attribut för pennstreck kan ställas in dynamiskt för att uppfylla användarinställningar eller appkrav.
Här låter vi en användare välja från en lista med bläckfärger.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0">
<TextBlock x:Name="Header"
Text="Basic ink customization sample"
VerticalAlignment="Center"
Style="{ThemeResource HeaderTextBlockStyle}"
Margin="10,0,0,0" />
<TextBlock Text="Color:"
Style="{StaticResource SubheaderTextBlockStyle}"
VerticalAlignment="Center"
Margin="50,0,10,0"/>
<ComboBox x:Name="PenColor"
VerticalAlignment="Center"
SelectedIndex="0"
SelectionChanged="OnPenColorChanged">
<ComboBoxItem Content="Black"/>
<ComboBoxItem Content="Red"/>
</ComboBox>
</StackPanel>
<Grid Grid.Row="1">
<Image Source="Assets\StoreLogo.png" />
<InkCanvas x:Name="inkCanvas" />
</Grid>
</Grid>
Sedan hanterar vi ändringar i den valda färgen och uppdaterar attributen för pennstreck i enlighet med detta.
// Update ink stroke color for new strokes.
private void OnPenColorChanged(object sender, SelectionChangedEventArgs e)
{
if (inkCanvas != null)
{
InkDrawingAttributes drawingAttributes =
inkCanvas.InkPresenter.CopyDefaultDrawingAttributes();
string value = ((ComboBoxItem)PenColor.SelectedItem).Content.ToString();
switch (value)
{
case "Black":
drawingAttributes.Color = Windows.UI.Colors.Black;
break;
case "Red":
drawingAttributes.Color = Windows.UI.Colors.Red;
break;
default:
drawingAttributes.Color = Windows.UI.Colors.Black;
break;
};
inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes);
}
}
Dessa bilder visar hur pennindata bearbetas och anpassas av InkPresenter.
InkCanvas med svarta pennstreck som standard.
InkCanvas med röda pennstreck markerade av användaren.
För att tillhandahålla funktioner utöver pennanteckning och radering, till exempel linjeval, måste din app identifiera specifika indata för InkPresenter- för att gå igenom obearbetade för hantering av din app.
Direktindata för avancerad bearbetning
Som standard bearbetar InkPresenter alla indata som antingen ett pennstreck eller ett raderingsdrag, inklusive indata som ändrats av en sekundär maskinvaruuppgång, till exempel en penntunnaknapp, en höger musknapp eller liknande. Användare förväntar sig dock vanligtvis några ytterligare funktioner eller förändrade beteenden med dessa sekundära funktioner.
I vissa fall kan du också behöva exponera ytterligare funktioner för pennor utan sekundära möjligheter (funktioner som vanligtvis inte är kopplade till pennspetsen), andra typer av inmatningsenheter eller någon form av ändrat beteende utifrån ett användarval i appens gränssnitt.
För att stödja detta kan InkPresenter konfigureras för att lämna specifika indata obearbetade. Den här obearbetade indata skickas sedan till din app för bearbetning.
Exempel – Använda obearbetade indata för att implementera streckval
Windows Ink-plattformen ger inte inbyggt stöd för åtgärder som kräver ändrade indata, till exempel linjeval. Om du vill ha stöd för funktioner som denna måste du tillhandahålla en anpassad lösning i dina appar.
Följande kodexempel (all kod finns i filerna MainPage.xaml och MainPage.xaml.cs) visar steg för steg hur du aktiverar streckmarkering när indata ändras med en penntubknapp (eller höger musknapp).
Först konfigurerar vi användargränssnittet i MainPage.xaml.
Här lägger vi till en duk (under InkCanvas) för att rita markeringslinjen. Om du använder ett separat lager för att rita markeringslinjen förblir InkCanvas och dess innehåll orört.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel x:Name="HeaderPanel" Orientation="Horizontal" Grid.Row="0"> <TextBlock x:Name="Header" Text="Advanced ink customization sample" VerticalAlignment="Center" Style="{ThemeResource HeaderTextBlockStyle}" Margin="10,0,0,0" /> </StackPanel> <Grid Grid.Row="1"> <!-- Canvas for displaying selection UI. --> <Canvas x:Name="selectionCanvas"/> <!-- Inking area --> <InkCanvas x:Name="inkCanvas"/> </Grid> </Grid>
I MainPage.xaml.cs deklarerar vi ett par globala variabler för att behålla referenser till aspekter av urvalsgränssnittet. Specifikt, markeringslasso-stroken och den avgränsningsrektangel som markerar valda streck.
// Stroke selection tool. private Polyline lasso; // Stroke selection area. private Rect boundingRect;
Därefter konfigurerar vi InkPresenter för att tolka indata från både pennan och musen som pennstreck och anger några inledande pennstrecksattribut som används för återgivningsstreck till InkCanvas.
Viktigast av allt är att vi använder egenskapen InputProcessingConfiguration för InkPresenter för att ange att eventuella ändrade indata ska bearbetas av appen. Ändrade indata anges genom att tilldela InputProcessingConfiguration.RightDragAction värdet InkInputRightDragAction.LeaveUnprocessed. När det här värdet har angetts går InkPresenter vidare till klassen InkUnprocessedInput , en uppsättning pekarhändelser som du kan hantera.
Vi tilldelar lyssnare för PointerPressed, PointerMovedoch PointerReleased händelser som skickas av InkPresenter. Alla urvalsfunktioner implementeras i hanterarna för dessa händelser.
Slutligen tilldelar vi lyssnare för StrokeStarted och StrokesErased händelserna hos InkPresenter. Vi använder händelsehanterare för dessa händelser för att rensa upp markeringsgränssnittet om en ny linje startas eller om en befintlig linje raderas.
public MainPage() { this.InitializeComponent(); // Set supported inking device types. inkCanvas.InkPresenter.InputDeviceTypes = Windows.UI.Core.CoreInputDeviceTypes.Mouse | Windows.UI.Core.CoreInputDeviceTypes.Pen; // Set initial ink stroke attributes. InkDrawingAttributes drawingAttributes = new InkDrawingAttributes(); drawingAttributes.Color = Windows.UI.Colors.Black; drawingAttributes.IgnorePressure = false; drawingAttributes.FitToCurve = true; inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes); // By default, the InkPresenter processes input modified by // a secondary affordance (pen barrel button, right mouse // button, or similar) as ink. // To pass through modified input to the app for custom processing // on the app UI thread instead of the background ink thread, set // InputProcessingConfiguration.RightDragAction to LeaveUnprocessed. inkCanvas.InkPresenter.InputProcessingConfiguration.RightDragAction = InkInputRightDragAction.LeaveUnprocessed; // Listen for unprocessed pointer events from modified input. // The input is used to provide selection functionality. inkCanvas.InkPresenter.UnprocessedInput.PointerPressed += UnprocessedInput_PointerPressed; inkCanvas.InkPresenter.UnprocessedInput.PointerMoved += UnprocessedInput_PointerMoved; inkCanvas.InkPresenter.UnprocessedInput.PointerReleased += UnprocessedInput_PointerReleased; // Listen for new ink or erase strokes to clean up selection UI. inkCanvas.InkPresenter.StrokeInput.StrokeStarted += StrokeInput_StrokeStarted; inkCanvas.InkPresenter.StrokesErased += InkPresenter_StrokesErased; }
Sedan definierar vi hanterare för de obearbetade händelserna PointerPressed, PointerMovedoch PointerReleased som gått igenom av InkPresenter.
Alla urvalsfunktioner implementeras i dessa hanterare, inklusive lasso-linjen och begränsningsrektangeln.
// Handle unprocessed pointer events from modified input. // The input is used to provide selection functionality. // Selection UI is drawn on a canvas under the InkCanvas. private void UnprocessedInput_PointerPressed( InkUnprocessedInput sender, PointerEventArgs args) { // Initialize a selection lasso. lasso = new Polyline() { Stroke = new SolidColorBrush(Windows.UI.Colors.Blue), StrokeThickness = 1, StrokeDashArray = new DoubleCollection() { 5, 2 }, }; lasso.Points.Add(args.CurrentPoint.RawPosition); selectionCanvas.Children.Add(lasso); } private void UnprocessedInput_PointerMoved( InkUnprocessedInput sender, PointerEventArgs args) { // Add a point to the lasso Polyline object. lasso.Points.Add(args.CurrentPoint.RawPosition); } private void UnprocessedInput_PointerReleased( InkUnprocessedInput sender, PointerEventArgs args) { // Add the final point to the Polyline object and // select strokes within the lasso area. // Draw a bounding box on the selection canvas // around the selected ink strokes. lasso.Points.Add(args.CurrentPoint.RawPosition); boundingRect = inkCanvas.InkPresenter.StrokeContainer.SelectWithPolyLine( lasso.Points); DrawBoundingRect(); }
För att avsluta händelsehanteraren PointerReleased rensar vi markeringslagret för allt innehåll (lasso-strecket) och ritar sedan en enda avgränsningsrektangel runt pennstrecken som omfattas av lasso-området.
// Draw a bounding rectangle, on the selection canvas, encompassing // all ink strokes within the lasso area. private void DrawBoundingRect() { // Clear all existing content from the selection canvas. selectionCanvas.Children.Clear(); // Draw a bounding rectangle only if there are ink strokes // within the lasso area. if (!((boundingRect.Width == 0) || (boundingRect.Height == 0) || boundingRect.IsEmpty)) { var rectangle = new Rectangle() { Stroke = new SolidColorBrush(Windows.UI.Colors.Blue), StrokeThickness = 1, StrokeDashArray = new DoubleCollection() { 5, 2 }, Width = boundingRect.Width, Height = boundingRect.Height }; Canvas.SetLeft(rectangle, boundingRect.X); Canvas.SetTop(rectangle, boundingRect.Y); selectionCanvas.Children.Add(rectangle); } }
Slutligen definierar vi hanterare för händelserna StrokeStarted och StrokesErased InkPresenter.
De båda anropar enbart samma rensningsfunktion för att rensa den aktuella markeringen när ett nytt streck identifieras.
// Handle new ink or erase strokes to clean up selection UI. private void StrokeInput_StrokeStarted( InkStrokeInput sender, Windows.UI.Core.PointerEventArgs args) { ClearSelection(); } private void InkPresenter_StrokesErased( InkPresenter sender, InkStrokesErasedEventArgs args) { ClearSelection(); }
Här är funktionen för att ta bort alla markeringsgränssnitt från markeringsarbetsytan när en ny linje startas eller en befintlig linje raderas.
// Clean up selection UI. private void ClearSelection() { var strokes = inkCanvas.InkPresenter.StrokeContainer.GetStrokes(); foreach (var stroke in strokes) { stroke.Selected = false; } ClearDrawnBoundingRect(); } private void ClearDrawnBoundingRect() { if (selectionCanvas.Children.Any()) { selectionCanvas.Children.Clear(); boundingRect = Rect.Empty; } }
Anpassad pennanteckningsåtergivning
Som standard bearbetas ink-indata på en bakgrundstråd med låg svarstid och återges som pågående, eller "våt" när den ritas. När strecket är klart (pennan eller fingret lyfts eller musknappen släpps) bearbetas strecket på användargränssnittstråden och återges "torrt" till InkCanvas-lagret (ovanför programinnehållet och ersätter den våta pennanteckningen).
Du kan åsidosätta det här standardbeteendet och helt styra pennanteckningsfunktionen genom att anpassa torkningen av de våta pennstrecken. Standardbeteendet räcker vanligtvis för de flesta program, men det finns några fall där anpassad torkning kan krävas, men följande är:
- Effektivare hantering av stora eller komplexa samlingar med pennstreck
- Mer effektivt stöd för panorering och zoomning på stora pennarbetsytor
- Sammanflätning av pennanteckningar och andra objekt, till exempel former eller text, samtidigt som z-ordningen bibehålls
- Torka och konvertera bläck synkront till en DirectX-form (till exempel en rät linje eller form som rastreras och integreras i programinnehåll i stället för som ett separat InkCanvas lager).
Anpassad bearbetning kräver ett IInkD2DRenderer objekt för att hantera pennanteckningsindata och återge den till Direct2D-enhetskontexten för din Universal Windows-app, istället för standardkontrollen InkCanvas.
Genom att anropa ActivateCustomDrying (innan InkCanvas läses in) skapar en app ett InkSynchronizer objekt för att anpassa hur ett bläckstråk torkas till en SurfaceImageSource eller en VirtualSurfaceImageSource.
Både SurfaceImageSource och VirtualSurfaceImageSource tillhandahåller en DirectX-delad yta för din app att rita i och komponera in i din apps innehåll. VSIS erbjuder dock en virtuell yta som är större än skärmen, vilket möjliggör effektivare panorering och zoomning. Eftersom visuella uppdateringar av dessa ytor synkroniseras med XAML UI-tråden kan den våta pennanteckningen tas bort från InkCanvas samtidigt när pennanteckning återges till någon av dem.
Du kan också anpassa torr pennanteckning till en SwapChainPanel, men synkronisering med användargränssnittstråden är inte garanterad och det kan uppstå en fördröjning mellan när pennanteckningen återges till SwapChainPanel och när pennanteckningen tas bort från InkCanvas.
Ett fullständigt exempel på den här funktionen finns i exemplet med komplex pennanteckning.
Anmärkning
Anpassad torkning och Inkverktygsfält
Om din app åsidosätter standardbeteendet för inkrendering av InkPresenter med en anpassad torkningsimplementering är de renderade pennstrecken inte längre tillgängliga för InkToolbar och de inbyggda raderingskommandona i InkToolbar fungerar inte som förväntat. För att tillhandahålla raderingsfunktioner måste du hantera alla pekarhändelser, utföra träfftestning för varje slag och åsidosätta det inbyggda kommandot "Radera alla pennanteckningar".
Andra artiklar i det här avsnittet
Ämne | Beskrivning |
---|---|
Identifiera bläckstreck | Konvertera pennstreck till text med handskriftsigenkänning eller till former med anpassad igenkänning. |
Lagra och hämta pennstreck | Lagra pennstrecksdata i en GIF-fil (Graphics Interchange Format) med hjälp av ISF-metadata (Embedded Ink Serialized Format). |
Lägga till en InkToolbar i en Windows-pennanteckningsapp | Lägg till ett standardverktygsfält i en pennanteckningsapp i en Windows-app, lägg till en anpassad pennknapp i InkToolbar och koppla den anpassade pennknappen till en anpassad penndefinition. |
Relaterade artiklar
- Kom igång: Stöd för pennanteckningar i din Windows-app
- Hantera pekarindata
- Identifiera inmatningsenheter
- Specifikation för bläckserialiserat format (ISF).
API:er
Exempel
- Kom igång Introduktion: Stöd för bläck i Windows-appen
- Exempel på enkel pennanteckning (C#/C++)
- Komplext bläck-exempel (C++)
- Bläckprov (JavaScript)
- färgboksexempel
- Exempel på familjeanteckningar
- Exempel på grundläggande indata
- exempel på indata med låg svarstid
- Exempel på interaktionsläge för användare
- Exempel på fokusvisualiseringar
Arkivera exempel
Windows developer