Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Existují dva různé ovládací prvky, které usnadňují rukopis v aplikacích Windows: InkCanvas a InkToolbar.
Ovládací prvek InkCanvas poskytuje základní funkcionalitu Windows Ink. Můžete ho použít k vykreslení vstupu pera buď jako inkoustového tahu (s použitím výchozích nastavení pro barvu a tloušťku), nebo jako mazacího tahu.
Podrobnosti o implementaci InkCanvas najdete v tématu o interakcích Pen a stylus v aplikacích Windows.
Jako zcela průhledné překrytí inkCanvas neposkytuje žádné integrované uživatelské rozhraní pro nastavení vlastností tahů rukopisu. Pokud chcete změnit výchozí prostředí rukopisu, nechte uživatele nastavit vlastnosti tahu rukopisem a podporovat další vlastní funkce rukopisu, máte dvě možnosti:
V kódu na pozadí použijte základní inkPresenter objekt vázaný na InkCanvas.
Rozhraní API InkPresenter podporují rozsáhlé přizpůsobení prostředí rukopisu. Další podrobnosti najdete v tématu o interakcích Pen a pera v aplikacích Windows.
Připojte InkToolbar na InkCanvas. InkToolbar ve výchozím nastavení nabízí přizpůsobitelnou a rozšiřitelnou kolekci tlačítek pro aktivaci funkcí souvisejících s rukopisem, jako je velikost tahu, barva rukopisu a tip pera.
Probereme InkToolbar v tomto tématu.
Important API: InkCanvas – třída, InkToolbar třída, InkPresenter třída, Windows. UI. Input.Inking
Výchozí inkToolbar
InkToolbar ve výchozím nastavení obsahuje tlačítka pro kreslení, mazání, zvýrazňování a zobrazení šablony (pravítko nebo úhloměr). V závislosti na funkci jsou další nastavení a příkazy, jako je barva inkoustu, tloušťka tahu, vymazání veškerého inkoustu, k dispozici v rozbalovacím menu.
Výchozí panel nástrojů Windows Ink
Pokud chcete do aplikace rukopisu přidat výchozí InkToolbar, stačí ho umístit na stejnou stránku jako InkCanvas a propojit oba ovládací prvky.
- V souboru MainPage.xaml deklarujte objekt kontejneru (v tomto příkladu používáme ovládací prvek Mřížka) pro povrch rukopisu.
- Deklarujte objekt InkCanvas jako potomka kontejneru. (Velikost InkCanvas je zděděna z kontejneru.)
- Deklarujte InkToolbar a použijte atribut TargetInkCanvas k vytvoření vazby na InkCanvas.
Poznámka:
Ujistěte se, že je InkToolbar deklarován za InkCanvas. Pokud ne, překrytí InkCanvas způsobí, že InkToolbar bude nepřístupný.
<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" />
<InkToolbar x:Name="inkToolbar"
VerticalAlignment="Top"
TargetInkCanvas="{x:Bind inkCanvas}" />
</Grid>
</Grid>
Základní přizpůsobení
V této části probereme některé základní scénáře přizpůsobení panelu nástrojů Windows Ink.
Určení umístění a orientace
Když do aplikace přidáte panel nástrojů rukopisu, můžete přijmout výchozí umístění a orientaci panelu nebo je nastavit podle potřeb vaší aplikace nebo uživatelských potřeb.
XAML
Explicitně zadejte umístění a orientaci panelu nástrojů prostřednictvím vlastností VerticalAlignment, HorizontalAlignment a Orientation .
| Výchozí | Explicitní |
|---|---|
|
|
| Výchozí umístění a orientace panelu nástrojů Windows Ink | Explicitní umístění a orientace panelu nástrojů Windows Ink |
Tady je kód pro explicitní nastavení umístění a orientace panelu nástrojů Ink v XAML.
<InkToolbar x:Name="inkToolbar"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Orientation="Vertical"
TargetInkCanvas="{x:Bind inkCanvas}" />
Inicializace na základě uživatelských předvoleb nebo stavu zařízení
V některých případech můžete chtít nastavit umístění a orientaci panelu nástrojů rukopisu na základě předvoleb uživatele nebo stavu zařízení. Následující příklad ukazuje, jak nastavit umístění a orientaci panelu nástrojů pro inkoust na základě předvoleb psaní levou nebo pravou rukou, určené prostřednictvím Nastavení > Zařízení > Pero & Windows Ink > Pero > Zvolte, kterou rukou píšete.
Nastavení pro dominantní ruku
Toto nastavení můžete získat pomocí vlastnosti HandPreference ve Windows.UI.ViewManagement a nastavit HorizontalAlignment na základě vrácené hodnoty. V tomto příkladu najdeme panel nástrojů na levé straně aplikace pro osobu s levou rukou a na pravé straně pro osobu s pravou rukou.
Stáhnout tuto ukázku z Ukázka umístění a orientace panelu nástrojů Rukopis (základní)
public MainPage()
{
this.InitializeComponent();
Windows.UI.ViewManagement.UISettings settings =
new Windows.UI.ViewManagement.UISettings();
HorizontalAlignment alignment =
(settings.HandPreference ==
Windows.UI.ViewManagement.HandPreference.LeftHanded) ?
HorizontalAlignment.Left : HorizontalAlignment.Right;
inkToolbar.HorizontalAlignment = alignment;
}
Dynamická úprava stavu uživatele nebo zařízení
Vazby můžete použít také ke sledování aktualizací uživatelského rozhraní na základě změn uživatelských předvoleb, nastavení zařízení nebo stavů zařízení. V následujícím příkladu rozšíříme předchozí příklad a ukážeme, jak pomocí vazby, objektu ViewModel a rozhraní INotifyPropertyChanged dynamicky umístit panel nástrojů rukopisu na základě orientace zařízení.
Stáhněte si tuto ukázku z Umístění a orientace panelu nástrojů Rukopis (dynamická)
Nejprve přidáme náš model ViewModel.
Přidejte do projektu novou složku a zavolejte ji ViewModels.
Přidejte novou třídu do složky ViewModels (v tomto příkladu jsme ji nazvali InkToolbarSnippetHostViewModel.cs).
Poznámka:
Použili jsme model Singleton , protože pro životnost aplikace potřebujeme pouze jeden objekt tohoto typu.
Přidejte
using System.ComponentModeljmenný prostor do souboru.Přidejte statickou členovou proměnnou s názvem instance a statickou vlastnost jen pro čtení s názvem Instance. Zajistěte, aby byl konstruktor privátní, aby byla tato třída přístupná pouze prostřednictvím vlastnosti Instance.
Poznámka:
Tato třída dědí z rozhraní INotifyPropertyChanged, které slouží k upozorňování klientů, obvykle klientů používajících datové vazby, že hodnota vlastnosti se změnila. Použijeme ho ke zpracování změn orientace zařízení (tento kód rozbalíme a vysvětlíme si ho v pozdějším kroku).
using System.ComponentModel; namespace locationandorientation.ViewModels { public class InkToolbarSnippetHostViewModel : INotifyPropertyChanged { private static InkToolbarSnippetHostViewModel instance; public static InkToolbarSnippetHostViewModel Instance { get { if (null == instance) { instance = new InkToolbarSnippetHostViewModel(); } return instance; } } } private InkToolbarSnippetHostViewModel() { } }Přidejte dvě logické vlastnosti do třídy InkToolbarSnippetHostViewModel: LeftHandedLayout (stejné funkce jako předchozí příklad jen XAML) a PortraitLayout (orientace zařízení).
Poznámka:
Vlastnost PortraitLayout je nastavitelná a obsahuje definici události PropertyChanged.
public bool LeftHandedLayout { get { bool leftHandedLayout = false; Windows.UI.ViewManagement.UISettings settings = new Windows.UI.ViewManagement.UISettings(); leftHandedLayout = (settings.HandPreference == Windows.UI.ViewManagement.HandPreference.LeftHanded); return leftHandedLayout; } } public bool portraitLayout = false; public bool PortraitLayout { get { Windows.UI.ViewManagement.ApplicationViewOrientation winOrientation = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().Orientation; portraitLayout = (winOrientation == Windows.UI.ViewManagement.ApplicationViewOrientation.Portrait); return portraitLayout; } set { if (value.Equals(portraitLayout)) return; portraitLayout = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("PortraitLayout")); } }
Teď do našeho projektu přidáme několik tříd převaděčů. Každá třída obsahuje Convert objekt, který vrací hodnotu zarovnání ( HorizontalAlignment nebo VerticalAlignment).
Přidejte do projektu novou složku a pojmenujte ji Převaděče.
Přidejte do složky Converters dvě nové třídy (v tomto příkladu je voláme HorizontalAlignmentFromHandednessConverter.cs a VerticalAlignmentFromAppViewConverter.cs).
Do každého souboru přidejte obory názvů
using Windows.UI.Xamlausing Windows.UI.Xaml.Data.Změňte každou třídu na
publica určete, že implementuje IValueConverter rozhraní.Přidejte metody Convert a ConvertBack do každého souboru, jak je znázorněno zde (ponecháme metodu ConvertBack bez rozšíření).
- HorizontalAlignmentFromHandednessConverter umístí panel nástrojů rukopisu na pravou stranu aplikace pro uživatele s pravou rukou a na levou stranu aplikace pro uživatele s levou rukou.
using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Data; namespace locationandorientation.Converters { public class HorizontalAlignmentFromHandednessConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { bool leftHanded = (bool)value; HorizontalAlignment alignment = HorizontalAlignment.Right; if (leftHanded) { alignment = HorizontalAlignment.Left; } return alignment; } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } }- VerticalAlignmentFromAppViewConverter umístí panel nástrojů rukopisu do středu aplikace pro orientaci na výšku a do horní části aplikace pro orientaci na šířku (i když je určen ke zlepšení použitelnosti, je to jen libovolná volba pro demonstrační účely).
using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Data; namespace locationandorientation.Converters { public class VerticalAlignmentFromAppViewConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { bool portraitOrientation = (bool)value; VerticalAlignment alignment = VerticalAlignment.Top; if (portraitOrientation) { alignment = VerticalAlignment.Center; } return alignment; } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } }
Teď otevřete soubor MainPage.xaml.cs.
- Přidejte
using using locationandorientation.ViewModelsdo seznamu jmenných prostorů pro přidružení modelu ViewModel. - Přidejte
using Windows.UI.ViewManagementdo seznamu oborů názvů pro umožnění sledování změn orientace zařízení. - Přidejte kód WindowSizeChangedEventHandler .
- Nastavte DataContext pro zobrazení na singleton instanci třídy InkToolbarSnippetHostViewModel.
using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using locationandorientation.ViewModels; using Windows.UI.ViewManagement; namespace locationandorientation { public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); Window.Current.SizeChanged += (sender, args) => { ApplicationView currentView = ApplicationView.GetForCurrentView(); if (currentView.Orientation == ApplicationViewOrientation.Landscape) { InkToolbarSnippetHostViewModel.Instance.PortraitLayout = false; } else if (currentView.Orientation == ApplicationViewOrientation.Portrait) { InkToolbarSnippetHostViewModel.Instance.PortraitLayout = true; } }; DataContext = InkToolbarSnippetHostViewModel.Instance; } } }- Přidejte
Dále otevřete soubor MainPage.xaml.
Přidejte
xmlns:converters="using:locationandorientation.Converters"do elementuPagepro vazbu s našimi převaděči.<Page x:Class="locationandorientation.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:locationandorientation" xmlns:converters="using:locationandorientation.Converters" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">Přidejte prvek
PageResourcesa zadejte odkazy na naše převaděče.<Page.Resources> <converters:HorizontalAlignmentFromHandednessConverter x:Key="HorizontalAlignmentConverter"/> <converters:VerticalAlignmentFromAppViewConverter x:Key="VerticalAlignmentConverter"/> </Page.Resources>Přidejte ovládací prvky InkCanvas a InkToolbar a svázat vlastnosti VerticalAlignment a HorizontalAlignment ovládacího prvku InkToolbar.
<InkCanvas x:Name="inkCanvas" /> <InkToolbar x:Name="inkToolbar" VerticalAlignment="{Binding PortraitLayout, Converter={StaticResource VerticalAlignmentConverter} }" HorizontalAlignment="{Binding LeftHandedLayout, Converter={StaticResource HorizontalAlignmentConverter} }" Orientation="Vertical" TargetInkCanvas="{x:Bind inkCanvas}" />
Vraťte se do souboru InkToolbarSnippetHostViewModel.cs a přidejte do třídy
PortraitLayoutnašeLeftHandedLayoutaInkToolbarSnippetHostViewModelbooleanové vlastnosti spolu s podporou pro opětovné přebindováníPortraitLayoutv případě, že se tato hodnota vlastnosti změní.public bool LeftHandedLayout { get { bool leftHandedLayout = false; Windows.UI.ViewManagement.UISettings settings = new Windows.UI.ViewManagement.UISettings(); leftHandedLayout = (settings.HandPreference == Windows.UI.ViewManagement.HandPreference.LeftHanded); return leftHandedLayout; } } public bool portraitLayout = false; public bool PortraitLayout { get { Windows.UI.ViewManagement.ApplicationViewOrientation winOrientation = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().Orientation; portraitLayout = (winOrientation == Windows.UI.ViewManagement.ApplicationViewOrientation.Portrait); return portraitLayout; } set { if (value.Equals(portraitLayout)) return; portraitLayout = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("PortraitLayout")); } } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string property) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } #endregion
Teď byste měli mít aplikaci pro psaní rukou, která se přizpůsobí dominantní ruce uživatele a dynamicky reaguje na orientaci zařízení uživatele.
Zadání vybraného tlačítka
Panel nástrojů Windows Ink s tlačítkem tužky vybraným na počátku
Ve výchozím nastavení je při spuštění aplikace vybráno první tlačítko (nebo úplně vlevo) a inicializuje se panel nástrojů. Ve výchozím panelu nástrojů Windows Ink se jedná o tlačítko kuličkového pera.
Vzhledem k tomu, že architektura definuje pořadí předdefinovaných tlačítek, nemusí být prvním tlačítkem pero nebo nástroj, které chcete ve výchozím nastavení aktivovat.
Toto výchozí chování můžete přepsat a určit vybrané tlačítko na panelu nástrojů.
V tomto příkladu inicializujeme výchozí panel nástrojů s vybraným tlačítkem tužky a aktivovanou tužkou (místo kuličkového pera).
- Použijte deklaraci XAML pro InkCanvas a InkToolbar z předchozího příkladu.
- V kódu nastavte obslužnou rutinu pro událost Načtení objektu InkToolbar.
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// Here, we set up InkToolbar event listeners.
/// </summary>
public MainPage_CodeBehind()
{
this.InitializeComponent();
// Add handlers for InkToolbar events.
inkToolbar.Loaded += inkToolbar_Loaded;
}
V obslužné rutině události Loaded:
- Získejte odkaz na vestavěné tlačítko InkToolbarPencilButton.
Předáním objektu InkToolbarTool.Pencil v metodě GetToolButton se vrátí objekt InkToolbarToolButton pro InkToolbarPencilButton.
- Nastavte ActiveTool na objekt vrácený v předchozím kroku.
/// <summary>
/// Handle the Loaded event of the InkToolbar.
/// By default, the active tool is set to the first tool on the toolbar.
/// Here, we set the active tool to the pencil button.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void inkToolbar_Loaded(object sender, RoutedEventArgs e)
{
InkToolbarToolButton pencilButton = inkToolbar.GetToolButton(InkToolbarTool.Pencil);
inkToolbar.ActiveTool = pencilButton;
}
Zadání předdefinovaných tlačítek
Konkrétní tlačítka zahrnutá při inicializaci
Jak už bylo zmíněno, panel nástrojů Windows Ink obsahuje sadu výchozích integrovaných tlačítek. Tato tlačítka se zobrazují v následujícím pořadí (zleva doprava):
- InkToolbarBallpointPenButton
- InkToolbarTlačítkoTužky
- Tlačítko zvýrazňovače na panelu nástrojů Ink
- InkToolbarEraserButton
- InkToolbarRulerButton
V tomto příkladu inicializujeme panel nástrojů pouze se zabudovanými tlačítky kuličkového pera, tužky a gumy.
Můžete to provést pomocí XAML nebo zákulisního kódu.
XAML
Upravte deklaraci XAML pro InkCanvas a InkToolbar z prvního příkladu.
- Přidejte atribut InitialControls a nastavte jeho hodnotu na None. Tím se vymaže výchozí kolekce předdefinovaných tlačítek.
- Přidejte konkrétní tlačítka InkToolbar vyžadovaná vaší aplikací. Zde přidáme pouze InkToolbarBallpointPenButton, InkToolbarPencilButton a InkToolbarEraserButton .
Poznámka:
Tlačítka se přidají na panel nástrojů v pořadí definovaném architekturou, nikoli na pořadí uvedené zde.
<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" />
<!-- Clear the default InkToolbar buttons by setting InitialControls to None. -->
<!-- Set the active tool to the pencil button. -->
<InkCanvas x:Name="inkCanvas" />
<InkToolbar x:Name="inkToolbar"
VerticalAlignment="Top"
TargetInkCanvas="{x:Bind inkCanvas}"
InitialControls="None">
<!--
Add only the ballpoint pen, pencil, and eraser.
Note that the buttons are added to the toolbar in the order
defined by the framework, not the order we specify here.
-->
<InkToolbarEraserButton />
<InkToolbarBallpointPenButton />
<InkToolbarPencilButton/>
</InkToolbar>
</Grid>
</Grid>
Code-behind
- Použijte deklaraci XAML pro InkCanvas a InkToolbar z prvního příkladu.
<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" />
<InkToolbar x:Name="inkToolbar"
VerticalAlignment="Top"
TargetInkCanvas="{x:Bind inkCanvas}" />
</Grid>
</Grid>
- V kódu nastavte obslužnou rutinu pro událost Načítací objektu InkToolbar.
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// Here, we set up InkToolbar event listeners.
/// </summary>
public MainPage_CodeBehind()
{
this.InitializeComponent();
// Add handlers for InkToolbar events.
inkToolbar.Loading += inkToolbar_Loading;
}
- Nastavte InitialControls na None(Žádný).
- Vytvořte odkazy na objekty pro tlačítka požadovaná vaší aplikací. Zde přidáme pouze InkToolbarBallpointPenButton, InkToolbarPencilButton a InkToolbarEraserButton .
Poznámka:
Tlačítka se přidají na panel nástrojů v pořadí definovaném architekturou, nikoli na pořadí uvedené zde.
- Přidejte tlačítka na inkToolbar.
/// <summary>
/// Handles the Loading event of the InkToolbar.
/// Here, we identify the buttons to include on the InkToolbar.
/// </summary>
/// <param name="sender">The InkToolbar</param>
/// <param name="args">The InkToolbar event data.
/// If there is no event data, this parameter is null</param>
private void inkToolbar_Loading(FrameworkElement sender, object args)
{
// Clear all built-in buttons from the InkToolbar.
inkToolbar.InitialControls = InkToolbarInitialControls.None;
// Add only the ballpoint pen, pencil, and eraser.
// Note that the buttons are added to the toolbar in the order
// defined by the framework, not the order we specify here.
InkToolbarBallpointPenButton ballpoint = new InkToolbarBallpointPenButton();
InkToolbarPencilButton pencil = new InkToolbarPencilButton();
InkToolbarEraserButton eraser = new InkToolbarEraserButton();
inkToolbar.Children.Add(eraser);
inkToolbar.Children.Add(ballpoint);
inkToolbar.Children.Add(pencil);
}
Vlastní tlačítka a funkce rukopisu
Kolekci tlačítek (a přidružených funkcí rukopisu), které jsou k dispozici prostřednictvím inkToolbaru, můžete přizpůsobit a rozšířit.
InkToolbar se skládá ze dvou různých skupin typů tlačítek:
- Skupina tlačítek "tool" obsahující předdefinovaná tlačítka kreslení, mazání a zvýrazňování. Tady jsou přidána vlastní pera a nástroje.
Poznámka Výběr funkcí se vzájemně vylučuje.
- Skupina přepínacích tlačítek obsahující předdefinované tlačítko pravítka. Sem se přidají vlastní přepínače.
Poznámka Funkce se vzájemně nevylučují a lze je používat souběžně s jinými aktivními nástroji.
V závislosti na požadované aplikaci a požadované funkci rukopisu můžete na inkToolbar přidat libovolná z následujících tlačítek (svázaných s vlastními funkcemi rukopisu):
- Vlastní pero – pero, pro které jsou vlastnosti barevné palety rukopisu a tipu pera, jako je tvar, otočení a velikost, definovány hostitelskou aplikací.
- Vlastní nástroj – nástroj bez psacího pera, určený hostitelskou aplikací.
- Vlastní přepínač – Nastaví stav funkce definované aplikací na zapnuto nebo vypnuto. Když je tato funkce zapnutá, funguje ve spojení s aktivním nástrojem.
Poznámka Pořadí zobrazení předdefinovaných tlačítek nelze změnit. Výchozí pořadí zobrazení je: kuličkové pero, tužka, zvýrazňovač, guma a pravítko. Vlastní pera se připojují k poslednímu výchozímu peru, vlastní tlačítka nástrojů se přidají mezi poslední tlačítko pera a tlačítko gumy a vlastní přepínací tlačítka se přidají za tlačítko pravítka. (Vlastní tlačítka se přidají v pořadí, v jakém jsou zadány.)
Vlastní pero
Můžete vytvořit vlastní pero (aktivované pomocí tlačítka vlastního pera), kde definujete paletu barev inkoustu a vlastnosti hrotu pera, jako je tvar, otočení a velikost.
Tlačítko vlastního kaligrafického pera
V tomto příkladu definujeme vlastní pero s širokým hrotem, který umožňuje základní kaligrafické inkoustové tahy. Také přizpůsobíme kolekci štětců v paletě zobrazené v informačním rámečku tlačítka.
Code-behind
Nejprve definujeme vlastní pero a určíme atributy kreslení v code-behind. Na toto vlastní pero později odkazujeme v XAML.
- Klikněte pravým tlačítkem na projekt v Solution Explorer a vyberte Přidat -> Nová položka.
- V části Visual C# –> Code přidejte nový soubor třídy a zavolejte ho CalligraphicPen.cs.
- V Calligraphic.cs nahraďte výchozí blok pomocí následujícího příkazu:
using System.Numerics;
using Windows.UI;
using Windows.UI.Input.Inking;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
- Určete, že CalligraphicPen třída je odvozena z InkToolbarCustomPen.
class CalligraphicPen : InkToolbarCustomPen
{
}
- Přepište CreateInkDrawingAttributesCore a určete vlastní velikost štětce a tahu.
class CalligraphicPen : InkToolbarCustomPen
{
protected override InkDrawingAttributes
CreateInkDrawingAttributesCore(Brush brush, double strokeWidth)
{
}
}
- Vytvořte objekt InkDrawingAttributes a nastavte obrazec tipu pera, otočení špičky, velikost tahu a barvu rukopisu.
class CalligraphicPen : InkToolbarCustomPen
{
protected override InkDrawingAttributes
CreateInkDrawingAttributesCore(Brush brush, double strokeWidth)
{
InkDrawingAttributes inkDrawingAttributes =
new InkDrawingAttributes();
inkDrawingAttributes.PenTip = PenTipShape.Circle;
inkDrawingAttributes.Size =
new Windows.Foundation.Size(strokeWidth, strokeWidth * 20);
SolidColorBrush solidColorBrush = brush as SolidColorBrush;
if (solidColorBrush != null)
{
inkDrawingAttributes.Color = solidColorBrush.Color;
}
else
{
inkDrawingAttributes.Color = Colors.Black;
}
Matrix3x2 matrix = Matrix3x2.CreateRotation(45);
inkDrawingAttributes.PenTipTransform = matrix;
return inkDrawingAttributes;
}
}
XAML
Dále přidáme potřebné odkazy na vlastní pero v MainPage.xaml.
- Deklarujeme slovník prostředků místní stránky, který vytvoří odkaz na uživatelské pero (
CalligraphicPen) definované v CalligraphicPen.cs a kolekci štětce podporovanou uživatelským perem (CalligraphicPenPalette).
<Page.Resources>
<!-- Add the custom CalligraphicPen to the page resources. -->
<local:CalligraphicPen x:Key="CalligraphicPen" />
<!-- Specify the colors for the palette of the custom pen. -->
<BrushCollection x:Key="CalligraphicPenPalette">
<SolidColorBrush Color="Blue" />
<SolidColorBrush Color="Red" />
</BrushCollection>
</Page.Resources>
- Pak přidáme InkToolbar s podřízeným elementem InkToolbarCustomPenButton .
Tlačítko pro vlastní pero obsahuje dva odkazy na statické prostředky deklarované v prostředcích stránky: CalligraphicPen a CalligraphicPenPalette.
Určujeme také rozsah posuvníku velikosti tahů (MinStrokeWidth, MaxStrokeWidth a SelectedStrokeWidth), vybraného štětce (SelectedBrushIndex) a ikony tlačítka vlastního pera (SymbolIcon).
<Grid Grid.Row="1">
<InkCanvas x:Name="inkCanvas" />
<InkToolbar x:Name="inkToolbar"
VerticalAlignment="Top"
TargetInkCanvas="{x:Bind inkCanvas}">
<InkToolbarCustomPenButton
CustomPen="{StaticResource CalligraphicPen}"
Palette="{StaticResource CalligraphicPenPalette}"
MinStrokeWidth="1" MaxStrokeWidth="3" SelectedStrokeWidth="2"
SelectedBrushIndex ="1">
<SymbolIcon Symbol="Favorite" />
<InkToolbarCustomPenButton.ConfigurationContent>
<InkToolbarPenConfigurationControl />
</InkToolbarCustomPenButton.ConfigurationContent>
</InkToolbarCustomPenButton>
</InkToolbar>
</Grid>
Vlastní přepínač
Můžete vytvořit vlastní přepínač (aktivovaný pomocí vlastního přepínacího tlačítka) a nastavit stav funkce definované aplikací na zapnutou nebo vypnutou. Když je tato funkce zapnutá, funguje ve spojení s aktivním nástrojem.
V tomto příkladu definujeme vlastní přepínací tlačítko, které umožňuje rukopis s dotykovým vstupem (ve výchozím nastavení není povolené dotykové rukopis).
Poznámka:
Pokud potřebujete podporovat rukopis pomocí dotykového ovládání, doporučujeme povolit ho pomocí tlačítka CustomToggleButton s ikonou a popisem uvedeným v tomto příkladu.
Vstup dotykového ovládání se obvykle používá pro přímou manipulaci s objektem nebo uživatelským rozhraním aplikace. Abychom ukázali rozdíly v chování při povoleném dotykovém rukopisu, umístíme InkCanvas do kontejneru ScrollViewer a nastavíme rozměry ScrollVieweru na menší než InkCanvas.
Když se aplikace spustí, podporuje se jenom rukopis pera a dotykové ovládání se používá k posouvání nebo přiblížení plochy rukopisu. Pokud je zapnuté dotykové ovládání rukopisu, nelze povrch rukopisu posouvat ani přibližovat dotykovým vstupem.
Poznámka:
Viz pokyny k ovládacím prvkům pro InkCanvas a InkToolbar ohledně uživatelského prostředí. Pro tento příklad jsou relevantní následující doporučení:
- Nástroj InkToolbar a rukopis obecně poskytují nejlepší zážitek při použití aktivního pera. V případě potřeby může vaše aplikace podporovat psaní myší a dotykem.
- Pokud podporujete rukopis s dotykovým vstupem, doporučujeme použít ikonu "ED5F" z písma Segoe MLD2 Assets pro přepínací tlačítko s popisem "Psaní dotykem".
XAML
- Nejprve deklarujeme prvek InkToolbarCustomToggleButton (toggleButton) s posluchačem události Click, který určuje zpracování události (Toggle_Custom).
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0"
x:Name="HeaderPanel"
Orientation="Horizontal">
<TextBlock x:Name="Header"
Text="Basic ink sample"
Style="{ThemeResource HeaderTextBlockStyle}"
Margin="10" />
</StackPanel>
<ScrollViewer Grid.Row="1"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<Grid HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<InkToolbar Grid.Row="0"
Margin="10"
x:Name="inkToolbar"
VerticalAlignment="Top"
TargetInkCanvas="{x:Bind inkCanvas}">
<InkToolbarCustomToggleButton
x:Name="toggleButton"
Click="CustomToggle_Click"
ToolTipService.ToolTip="Touch Writing">
<SymbolIcon Symbol="{x:Bind TouchWritingIcon}"/>
</InkToolbarCustomToggleButton>
</InkToolbar>
<ScrollViewer Grid.Row="1"
Height="500"
Width="500"
x:Name="scrollViewer"
ZoomMode="Enabled"
MinZoomFactor=".1"
VerticalScrollMode="Enabled"
VerticalScrollBarVisibility="Auto"
HorizontalScrollMode="Enabled"
HorizontalScrollBarVisibility="Auto">
<Grid x:Name="outputGrid"
Height="1000"
Width="1000"
Background="{ThemeResource SystemControlBackgroundChromeWhiteBrush}">
<InkCanvas x:Name="inkCanvas"/>
</Grid>
</ScrollViewer>
</Grid>
</ScrollViewer>
</Grid>
Code-behind
V předchozím fragmentu kódu jsme deklarovali naslouchací proces a obslužnou rutinu události Click (Toggle_Custom) na vlastním přepínacím tlačítku pro dotykové rukopisy (toggleButton). Tato obslužná rutina jednoduše přepíná podporu CoreInputDeviceTypes.Touch prostřednictvím vlastnosti InputDeviceTypes objektu InkPresenter.
Také jsme pro tlačítko zadali ikonu pomocí elementu SymbolIcon a rozšíření značek {x:Bind}, které ho sváže s polem definovaným v souboru s kódem (TouchWritingIcon).
Následující fragment kódu obsahuje obslužnou rutinu události Click i definici TouchWritingIcon.
namespace Ink_Basic_InkToolbar
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage_AddCustomToggle : Page
{
Symbol TouchWritingIcon = (Symbol)0xED5F;
public MainPage_AddCustomToggle()
{
this.InitializeComponent();
}
// Handler for the custom toggle button that enables touch inking.
private void CustomToggle_Click(object sender, RoutedEventArgs e)
{
if (toggleButton.IsChecked == true)
{
inkCanvas.InkPresenter.InputDeviceTypes |= CoreInputDeviceTypes.Touch;
}
else
{
inkCanvas.InkPresenter.InputDeviceTypes &= ~CoreInputDeviceTypes.Touch;
}
}
}
}
Vlastní nástroj
Můžete vytvořit vlastní tlačítko nástroje k vyvolání nástroje, který není perový a který je definován vaší aplikací.
Ve výchozím nastavení zpracovává InkPresenter všechny vstupy jako tah rukopisu nebo mazací tah. To zahrnuje vstup modifikovaný sekundární hardwarovou funkcí, jako je tlačítko na těle pera, pravé tlačítko myši nebo podobné. Ale InkPresenter je možné nakonfigurovat tak, aby ponechal konkrétní vstup nezpracovaný, který pak můžete předat do aplikace pro vlastní zpracování.
V tomto příkladu definujeme vlastní tlačítko nástrojů, které po výběru vyvolá zpracování a vykreslení následujících tahů jako laso výběru (přerušovaná čára) místo rukopisu. Všechny tahy rukopisu v mezích oblasti výběru jsou nastaveny jako vybrány.
Poznámka:
Vizte ovládací prvky rukopisu pro pokyny pro InkCanvas i InkToolbar. Následující doporučení je relevantní pro tento příklad:
- Pokud poskytujete výběr tahů, doporučujeme pro tlačítko nástroje použít ikonu EF20 z písma Segoe MLD2 Assets s popisem nástroje.
XAML
Nejprve deklarujeme element InkToolbarCustomToolButton (customToolButton) s naslouchacím procesem události Click, který určuje obslužnou rutinu události (customToolButton_Click), kde je nakonfigurován výběr tahu. (Přidali jsme také sadu tlačítek pro kopírování, vyjmutí a vkládání výběru tahů.)
Přidáme také prvek Canvas pro kreslení našeho výběrového tahu. Použití samostatné vrstvy k vykreslení tahu výběru zajistí, že InkCanvas a jeho obsah zůstanou nedotčené.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<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>
<StackPanel x:Name="ToolPanel" Orientation="Horizontal" Grid.Row="1">
<InkToolbar x:Name="inkToolbar"
VerticalAlignment="Top"
TargetInkCanvas="{x:Bind inkCanvas}">
<InkToolbarCustomToolButton
x:Name="customToolButton"
Click="customToolButton_Click"
ToolTipService.ToolTip="Selection tool">
<SymbolIcon Symbol="{x:Bind SelectIcon}"/>
</InkToolbarCustomToolButton>
</InkToolbar>
<Button x:Name="cutButton"
Content="Cut"
Click="cutButton_Click"
Width="100"
Margin="5,0,0,0"/>
<Button x:Name="copyButton"
Content="Copy"
Click="copyButton_Click"
Width="100"
Margin="5,0,0,0"/>
<Button x:Name="pasteButton"
Content="Paste"
Click="pasteButton_Click"
Width="100"
Margin="5,0,0,0"/>
</StackPanel>
<Grid Grid.Row="2" x:Name="outputGrid"
Background="{ThemeResource SystemControlBackgroundChromeWhiteBrush}"
Height="Auto">
<!-- Canvas for displaying selection UI. -->
<Canvas x:Name="selectionCanvas"/>
<!-- Canvas for displaying ink. -->
<InkCanvas x:Name="inkCanvas" />
</Grid>
</Grid>
Code-behind
Potom obsloužíme událost Click pro InkToolbarCustomToolButton v souboru kódu na pozadí MainPage.xaml.cs.
Tato obslužná rutina nakonfiguruje InkPresenter tak, aby aplikaci předala nezpracovaný vstup.
Podrobnější popis tohoto kódu: Viz sekci předávání vstupu pro pokročilé zpracování Interakce pera a Windows Ink v aplikacích Windows.
Také jsme pro tlačítko zadali ikonu pomocí elementu SymbolIcon a rozšíření značek {x:Bind}, které ho sváže s polem definovaným v souboru kódu (SelectIcon).
Následující fragment kódu obsahuje obslužnou rutinu události Click i definici selectIconu.
namespace Ink_Basic_InkToolbar
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage_AddCustomTool : Page
{
// Icon for custom selection tool button.
Symbol SelectIcon = (Symbol)0xEF20;
// Stroke selection tool.
private Polyline lasso;
// Stroke selection area.
private Rect boundingRect;
public MainPage_AddCustomTool()
{
this.InitializeComponent();
// Listen for new ink or erase strokes to clean up selection UI.
inkCanvas.InkPresenter.StrokeInput.StrokeStarted +=
StrokeInput_StrokeStarted;
inkCanvas.InkPresenter.StrokesErased +=
InkPresenter_StrokesErased;
}
private void customToolButton_Click(object sender, RoutedEventArgs e)
{
// 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;
}
// 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();
}
private void cutButton_Click(object sender, RoutedEventArgs e)
{
inkCanvas.InkPresenter.StrokeContainer.CopySelectedToClipboard();
inkCanvas.InkPresenter.StrokeContainer.DeleteSelected();
ClearSelection();
}
private void copyButton_Click(object sender, RoutedEventArgs e)
{
inkCanvas.InkPresenter.StrokeContainer.CopySelectedToClipboard();
}
private void pasteButton_Click(object sender, RoutedEventArgs e)
{
if (inkCanvas.InkPresenter.StrokeContainer.CanPasteFromClipboard())
{
inkCanvas.InkPresenter.StrokeContainer.PasteFromClipboard(
new Point(0, 0));
}
else
{
// Cannot paste from clipboard.
}
}
// Clean up selection UI.
private void ClearSelection()
{
var strokes = inkCanvas.InkPresenter.StrokeContainer.GetStrokes();
foreach (var stroke in strokes)
{
stroke.Selected = false;
}
ClearBoundingRect();
}
private void ClearBoundingRect()
{
if (selectionCanvas.Children.Any())
{
selectionCanvas.Children.Clear();
boundingRect = Rect.Empty;
}
}
// 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();
}
// 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);
}
}
}
}
Vlastní vykreslování rukopisu
Ve výchozím nastavení se rukopisný vstup zpracovává ve vlákně na pozadí s nízkou latencí a při vykreslení je "mokrý". Po dokončení tahu (když zvednete pero nebo prst nebo uvolníte tlačítko myši) se tah zpracuje ve vlákně uživatelského rozhraní a je vykreslen „suchý“ na vrstvu InkCanvas (nad obsah aplikace, kde nahradí mokrý inkoust).
Platforma rukopisu umožňuje toto chování přepsat a zcela přizpůsobit prostředí rukopisu vlastním vysycháním vstupu rukopisu.
Další informace o vlastním sušení najdete v tématu interakce Pen a Windows Rukopis v aplikacích Windows.
Poznámka:
Vlastní sušení a InkToolbar
Pokud vaše aplikace přepíše výchozí chování vykreslování rukopisu InkPresenter vlastní implementací sušení, vykreslené tahy rukopisu už nebudou dostupné pro InkToolbar a jeho integrované příkazy pro mazání nefungují podle očekávání. Chcete-li zajistit funkci vymazání, musíte zpracovat všechny události ukazatele, provést kolizní testování na každém tahu a přepsat vestavěný příkaz "Vymazat vše rukopis."
Související články
Ukázky témat
- Umístění a orientace panelu nástrojů Inku (základní)
- Ukázka umístění a orientace panelu rukopisu (dynamická)
Další ukázky
- Jednoduchá ukázka inkoustu (C#/C++)
- ukázka inkoustu komplexní (C++)
- Ukázka vzorku Ink (JavaScript)
- Get Started Tutorial: Podpora rukopisu v aplikaci Windows
- Ukázka omalovánky
- Ukázka rodinných poznámek