Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Windows uygulamalarında mürekkep oluşturma işlemini kolaylaştıran iki farklı denetim vardır: InkCanvas ve InkToolbar.
InkCanvas denetimi temel Windows Ink işlevselliği sağlar. Kalem girişini mürekkep vuruşu (renk ve kalınlık için varsayılan ayarları kullanarak) veya silme vuruşu olarak işlemek için kullanın.
InkCanvas uygulama ayrıntıları için bkz. Windows uygulamalarında Kalem ve ekran kalemi etkileşimleri.
Tamamen saydam bir katman olarak, InkCanvas mürekkep vuruşu özelliklerini ayarlamak için herhangi bir yerleşik kullanıcı arabirimi sağlamaz. Varsayılan mürekkep oluşturma deneyimini değiştirmek, kullanıcıların mürekkep vuruşu özelliklerini ayarlamasına izin vermek ve diğer özel mürekkep oluşturma özelliklerini desteklemek istiyorsanız iki seçeneğiniz vardır:
Arka plan kodunda, InkCanvas'a bağlı temel InkPresenter nesnesini kullanın.
InkPresenter API'leri, mürekkep oluşturma deneyiminin kapsamlı özelleştirmesini destekler. Daha fazla ayrıntı için bkz. Windows uygulamalarında kalem ve ekran kalemi etkileşimleri.
InkCanvas'a bir InkToolbar bağlayın. InkToolbar varsayılan olarak vuruş boyutu, mürekkep rengi ve kalem ucu gibi mürekkeple ilgili özellikleri etkinleştirmek için özelleştirilebilir ve genişletilebilir bir düğme koleksiyonu sağlar.
Bu konu başlığında InkToolbar'a değineceğiz.
Önemli API'ler: InkCanvas sınıfı, InkToolbar sınıfı, InkPresenter sınıfı, Windows.UI.Input.Inking
Varsayılan InkToolbar
InkToolbar varsayılan olarak bir kalıbı (cetvel veya protraktör) çizme, silme, vurgulama ve görüntüleme düğmeleri içerir. Özelliğe bağlı olarak, mürekkep rengi, vuruş kalınlığı, tüm mürekkebİ silme gibi diğer ayarlar ve komutlar açılır öğede sağlanır.
Varsayılan Windows Ink araç çubuğu
Mürekkep oluşturma uygulamasına varsayılan bir InkToolbar eklemek için, bunu InkCanvas ile aynı sayfaya yerleştirmeniz ve iki denetimi ilişkilendirmeniz gerekir.
- MainPage.xaml dosyasında, çizim yüzeyi için bir kapsayıcı nesne (bu örnekte Grid denetimi kullanıyoruz) bildirin.
- InkCanvas nesnesini bir kapsayıcının alt öğesi olarak tanımlayın. InkCanvas boyutu kapsayıcıdan devralınır.
- InkToolbar bildirin ve TargetInkCanvas özniteliğini kullanarak InkCanvas'e bağlayın.
Uyarı
InkToolbar'ın InkCanvas'dan sonra bildirildiğinden emin olun. Aksi takdirde, InkCanvas katmanı InkToolbar'a erişilemez hale getirir.
<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>
Temel özelleştirme
Bu bölümde bazı temel Windows Ink araç çubuğu özelleştirme senaryolarını ele alacağız.
Konum ve yönlendirmeyi belirtme
Uygulamanıza bir mürekkep araç çubuğu eklediğinizde, araç çubuğunun varsayılan konumunu ve yönlendirmesini kabul edebilir veya bunları uygulamanız veya kullanıcınız için gerektiği şekilde ayarlayabilirsiniz.
XAML
Araç çubuğunun konumunu ve yönlendirmesini VerticalAlignment, HorizontalAlignment ve Orientation özellikleri aracılığıyla açıkça belirtin.
| Varsayılan | Açık |
|---|---|
|
|
| Windows Ink araç çubuğu varsayılan konumu ve yönlendirmesi | Windows Ink araç çubuğu açık konum ve yönlendirme |
XAML'de mürekkep araç çubuğunun konumunu ve yönlendirmesini açıkça ayarlamaya yönelik kod aşağıdadır.
<InkToolbar x:Name="inkToolbar"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Orientation="Vertical"
TargetInkCanvas="{x:Bind inkCanvas}" />
Kullanıcı tercihlerine veya cihaz durumuna göre başlatma
Bazı durumlarda, mürekkep araç çubuğunun konumunu ve yönlendirmesini kullanıcı tercihine veya cihaz durumuna göre ayarlamak isteyebilirsiniz. Aşağıdaki örnekte , Ayarlar > Cihazlar > Kalemi ve Windows Mürekkep > Kalemi > Hangi elle yazdığınızı seçin aracılığıyla belirtilen sol veya sağ yazma tercihlerine göre mürekkep araç çubuğunun konumunu ve yönlendirmesini ayarlama işlemi gösterilmektedir.
Baskın el ayarı
Bu ayarı Windows.UI.ViewManagement'ın HandPreference özelliği aracılığıyla sorgulayabilir ve döndürülen değere göre HorizontalAlignment değerini ayarlayabilirsiniz. Bu örnekte, araç çubuğunu solak bir kişi için uygulamanın sol tarafında ve sağlak bir kişi için sağ tarafında konumlandırıyoruz.
Bu örneği Mürekkep araç çubuğu konumu ve yönü örneği (temel)'nden indirin
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;
}
Kullanıcı veya cihaz durumuna dinamik olarak ayarlama
Kullanıcı tercihlerinde, cihaz ayarlarında veya cihaz durumlarında yapılan değişikliklere göre kullanıcı arabirimi güncelleştirmelerine bakmak için bağlamayı da kullanabilirsiniz. Aşağıdaki örnekte, önceki örneği genişletir ve bağlama, ViewMOdel nesnesi ve INotifyPropertyChanged arabirimini kullanarak mürekkep araç çubuğunu cihaz yönlendirmesine göre dinamik olarak konumlandırmayı gösteririz.
Bu örneği Mürekkep araç çubuğunun konumu ve yönlendirmesi örneğinden (dinamik) indirin
İlk olarak ViewModel'imizi ekleyelim.
Projenize yeni bir klasör ekleyin ve Buna ViewModels adını verin.
ViewModels klasörüne yeni bir sınıf ekleyin (bu örnekte InkToolbarSnippetHostViewModel.cs olarak adlandırdık).
Uyarı
Uygulamanın ömrü boyunca bu türdeki tek bir nesneye ihtiyacımız olduğundan Singleton desenini kullandık
Dosyaya ad alanı ekleyin
using System.ComponentModel.instance adlı bir statik üye değişkeni ve Instance adlı statik salt okunur bir özellik ekleyin. Bu sınıfa yalnızca Instance özelliği aracılığıyla erişilebildiğinden emin olmak için oluşturucuyu özel hale getirin.
Uyarı
Bu sınıf INotifyPropertyChanged arabiriminden devralır. Bu arabirim, istemcilere genellikle bağlanan istemcilere bir özellik değerinin değiştiğini bildirmek için kullanılır. Cihaz yönlendirmesindeki değişiklikleri işlemek için bunu kullanacağız (bu kodu genişletecek ve sonraki bir adımda daha ayrıntılı açıklayacağız).
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() { } }InkToolbarSnippetHostViewModel sınıfına iki bool özelliği ekleyin: LeftHandedLayout (önceki XAML-only örneğiyle aynı işlevsellik) ve PortraitLayout (cihazın yönü).
Uyarı
PortraitLayout özelliği ayarlanabilir ve PropertyChanged olayının tanımını içerir.
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")); } }
Şimdi projemize birkaç dönüştürücü sınıfı ekleyelim. Her sınıf, hizalama değeri ( HorizontalAlignment veya VerticalAlignment) döndüren bir Convert nesnesi içerir.
Projenize yeni bir klasör ekleyin ve Buna Dönüştürücüler adını verin.
Dönüştürücüler klasörüne iki yeni sınıf ekleyin (bu örnekte bunları HorizontalAlignmentFromHandednessConverter.cs ve VerticalAlignmentFromAppViewConverter.cs olarak adlandırıyoruz).
Her dosyaya
using Windows.UI.Xamlveusing Windows.UI.Xaml.Dataad alanlarını ekleyin.Her sınıfı olarak
publicdeğiştirin ve IValueConverter arabirimini uygulayacağını belirtin.Burada gösterildiği gibi her dosyaya Convert ve ConvertBack yöntemlerini ekleyin (ConvertBack yöntemini engellenmemiş olarak bırakıyoruz).
- HorizontalAlignmentFromHandednessConverter, mürekkep araç çubuğunu sağ elini kullanan kullanıcılar için uygulamanın sağ tarafına, sol elini kullanan kullanıcılar için ise uygulamanın sol tarafına konumlandırır.
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, Ink Toolbar'ı dikey yönlendirmede uygulamanın merkezine, yatay yönlendirmede ise uygulamanın en üstüne konumlandırır. Kullanılabilirliği artırmak amacı güdülse de, bu sadece gösterim amacıyla yapılan keyfi bir seçimdir.
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(); } } }
Şimdi MainPage.xaml.cs dosyasını açın.
- ViewModel'imizi ilişkilendirmek için ad alanları listesine ekleyin
using using locationandorientation.ViewModels. - Cihaz yönlendirmesinde yapılan değişiklikleri dinlemeyi etkinleştirmek için ad alanları listesine ekleyin
using Windows.UI.ViewManagement. - WindowSizeChangedEventHandler kodunu ekleyin.
- Görünümün DataContext değerini InkToolbarSnippetHostViewModel sınıfının tekil örneğine ayarlayın.
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; } } }- ViewModel'imizi ilişkilendirmek için ad alanları listesine ekleyin
Ardından MainPage.xaml dosyasını açın.
xmlns:converters="using:locationandorientation.Converters"öğesine, dönüştürücülerimize bağlamak içinPageekleyin.<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">PageResourcesöğesi ekledikten sonra dönüştürücülerimize referansları belirterek devam edin.<Page.Resources> <converters:HorizontalAlignmentFromHandednessConverter x:Key="HorizontalAlignmentConverter"/> <converters:VerticalAlignmentFromAppViewConverter x:Key="VerticalAlignmentConverter"/> </Page.Resources>InkCanvas ve InkToolbar öğelerini ekleyin ve InkToolbar'ın VerticalAlignment ve HorizontalAlignment özelliklerini bağlayın.
<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}" />
InkToolbarSnippetHostViewModel.cs dosyasına dönün ve
PortraitLayoutveLeftHandedLayoutadındaki bool özelliklerimiziInkToolbarSnippetHostViewModelsınıfına ekleyin, ayrıca bu özelliklerin değeri değiştiğinde yeniden bağlama desteği sağlayı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
Artık hem kullanıcının baskın el tercihine uyum sağlayan hem de kullanıcının cihazının yönlendirmesine dinamik olarak yanıt veren bir mürekkep oluşturma uygulamanız olmalıdır.
Seçili düğmeyi belirtin
Başlatma sırasında kalem düğmesinin seçili olduğu Windows Ink araç çubuğu
Varsayılan olarak, uygulamanız başlatıldığında ve araç çubuğu başlatıldığında ilk (veya en soldaki) düğme seçilir. Varsayılan Windows Ink araç çubuğunda, bu tükenmez kalem düğmesidir.
Çerçeve yerleşik düğmelerin sırasını tanımladığından, ilk düğme varsayılan olarak etkinleştirmek istediğiniz kalem veya araç olmayabilir.
Bu varsayılan davranışı geçersiz kılabilir ve araç çubuğunda seçili düğmeyi belirtebilirsiniz.
Bu örnekte, kalem düğmesi seçili ve kalem etkinleştirilmiş (tükenmez kalem yerine) varsayılan araç çubuğunu başlatıyoruz.
- Önceki örnekteki InkCanvas ve InkToolbar için XAML bildirimini kullanın.
- Arka planda kodda, InkToolbar nesnesinin Loaded olayı için bir işleyici ayarlayın.
/// <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;
}
Loaded olayının işleyicisinde:
- Yerleşik InkToolbarPencilButton öğesine bir başvuru alın.
GetToolButton yönteminde bir InkToolbarTool.Pencil nesnesi geçirilirken, InkToolbarPencilButton için bir InkToolbarToolButton nesnesi döndürülüyor.
- ActiveTool'ı önceki adımda döndürülen nesneye ayarlayın.
/// <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;
}
Yerleşik düğmeleri belirtme
Başlatmaya dahil edilen belirli düğmeler
Belirtildiği gibi, Windows Ink araç çubuğu varsayılan, yerleşik düğmelerden oluşan bir koleksiyon içerir. Bu düğmeler şu sırada görüntülenir (soldan sağa):
- InkToolbarBallpointPenButton
- MürekkepAraçÇubuğuKalemDüğmesi
- InkToolbarHighlighterButton
- Mürekkep Araç Çubuğu Silgi Düğmesi (InkToolbarEraserButton)
- InkToolbarRulerButton
Bu örnekte araç çubuğunu yalnızca yerleşik tükenmez kalem, kalem ve silgi düğmeleriyle başlatıyoruz.
Bunu XAML veya arka planda kod kullanarak yapabilirsiniz.
XAML
İlk örnekten InkCanvas ve InkToolbar için XAML bildirimini değiştirin.
- InitialControls özniteliğini ekleyin ve değerini "Yok" olarak ayarlayın. Bu, varsayılan yerleşik düğme koleksiyonunu temizler.
- Uygulamanızın gerektirdiği belirli InkToolbar düğmelerini ekleyin. Burada yalnızca InkToolbarBallpointPenButton, InkToolbarPencilButton ve InkToolbarEraserButton değerlerini ekleyeceğiz.
Uyarı
Düğmeler araç çubuğuna burada belirtilen sırayla değil, çerçeve tarafından tanımlanan sırayla eklenir.
<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>
Arka planda kod
- İlk örnekten InkCanvas ve InkToolbar için XAML bildirimini kullanın.
<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>
- Arka planda kodda, InkToolbar nesnesinin Yükleme olayı için bir işleyici ayarlayın.
/// <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;
}
- InitialControls değerini "Yok" olarak ayarlayın.
- Uygulamanızın gerektirdiği düğmeler için nesne başvuruları oluşturun. Burada yalnızca InkToolbarBallpointPenButton, InkToolbarPencilButton ve InkToolbarEraserButton değerlerini ekleyeceğiz.
Uyarı
Düğmeler araç çubuğuna burada belirtilen sırayla değil, çerçeve tarafından tanımlanan sırayla eklenir.
- Düğmeleri InkToolbar'a ekleyin.
/// <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);
}
Özel düğmeler ve dijital kalem özellikleri
InkToolbar aracılığıyla sağlanan düğme koleksiyonunu (ve ilişkili mürekkep oluşturma özelliklerini) özelleştirebilir ve genişletebilirsiniz.
InkToolbar iki ayrı düğme türünden oluşur:
- Yerleşik çizim, silme ve vurgulama düğmelerini içeren bir grup "araç" düğmesi. Özel kalemler ve araçlar buraya eklenir.
Not Özellik seçimi birbirini dışlar.
- "Yerleşik cetvel düğmesini içeren bir grup 'aç/kapa' düğmesi." Özel düğmeler buraya eklenir.
Not Özellikler birbirini dışlamaz ve diğer etkin araçlarla aynı anda kullanılabilir.
Uygulamanıza ve gerekli mürekkep oluşturma işlevine bağlı olarak, Aşağıdaki düğmelerden herhangi birini (özel mürekkep özelliklerinize bağlı) InkToolbar'a ekleyebilirsiniz:
- Özel kalem: Mürekkep renk paleti ve şekil, dönme açısı ve boyut gibi kalem ucu özelliklerinin ana uygulama tarafından tanımlandığı kalem.
- Özel araç - barındırıcı uygulama tarafından tanımlanan kalem olmayan bir araç.
- Özel geçiş – Uygulama tanımlı bir özelliğin durumunu açık veya kapalı olarak ayarlar. Özellik açıldığında etkin araçla birlikte çalışır.
Not Yerleşik düğmelerin görüntüleme sırasını değiştiremezsiniz. Varsayılan görüntüleme sırası: Tükenmez kalem, kalem, vurgulayıcı, silgi ve cetvel. Özel kalemler son varsayılan kaleme eklenir, son kalem düğmesi arasına özel araç düğmeleri eklenir ve cetvel düğmesinden sonra silgi düğmesi ve özel geçiş düğmeleri eklenir. (Özel düğmeler belirtildikleri sırayla eklenir.)
Özel kalem
Mürekkep rengi paletini ve şekil, döndürme ve boyut gibi kalem ipucu özelliklerini tanımladığınız özel bir kalem (özel kalem düğmesiyle etkinleştirilir) oluşturabilirsiniz.
Özel kaligrafi kalemi düğmesi
Bu örnekte, temel kaligrafik mürekkep vuruşlarına olanak tanıyan geniş bir uca sahip özel bir kalem tanımladık. Düğme açılır öğesinde görüntülenen paletteki fırça koleksiyonunu da özelleştiriyoruz.
Arka planda kod
İlk olarak, özel kalemimizi tanımlayacak ve kod arkasında çizim özniteliklerini belirleyeceğiz. Bu özel kaleme daha sonra XAML'den başvuracağız.
- Çözüm Gezgini'nde projeye sağ tıklayın ve Ekle -> Yeni öğe'yi seçin.
- Visual C# -> Kod altında yeni bir Sınıf dosyası ekleyin ve CalligraphicPen.cs olarak adlandırın.
- Calligraphic.cs'da, varsayılan using block değerini aşağıdakilerle değiştirin:
using System.Numerics;
using Windows.UI;
using Windows.UI.Input.Inking;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
- CalligraphicPen sınıfının InkToolbarCustomPen'den türetildiğini belirtin.
class CalligraphicPen : InkToolbarCustomPen
{
}
- Kendi fırça ve vuruş boyutunuzu belirtmek için CreateInkDrawingAttributesCore'u geçersiz kılın.
class CalligraphicPen : InkToolbarCustomPen
{
protected override InkDrawingAttributes
CreateInkDrawingAttributesCore(Brush brush, double strokeWidth)
{
}
}
- InkDrawingAttributes nesnesi oluşturun ve kalem ucu şeklini, uç döndürmesini, vuruş boyutunu ve mürekkep rengini ayarlayın.
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
Ardından MainPage.xaml dosyasındaki özel kaleme gerekli referansları ekleyeceğiz.
- CalligraphicPen.cs'de tanımlanan özel kaleme (
CalligraphicPen) başvuru oluşturan bir yerel sayfa kaynak sözlüğü ve özel kalem tarafından desteklenen bir fırça koleksiyonu oluştururuz.
<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>
- Ardından alt InkToolbarCustomPenButton öğesiyle bir InkToolbar ekleriz.
Özel kalem düğmesi, sayfa kaynaklarında bildirilen iki statik kaynak başvurusu içerir: CalligraphicPen ve CalligraphicPenPalette.
Ayrıca vuruş boyutu kaydırıcısının (MinStrokeWidth, MaxStrokeWidth ve SelectedStrokeWidth), seçili fırçanın (SelectedBrushIndex) aralığını ve özel kalem düğmesinin (SymbolIcon) simgesini belirtiriz.
<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>
Özel geçiş
Uygulama tanımlı bir özelliğin durumunu açık veya kapalı olarak ayarlamak için özel bir geçiş düğmesi (özel geçiş düğmesiyle etkinleştirilir) oluşturabilirsiniz. Özellik açıldığında etkin araçla birlikte çalışır.
Bu örnekte, dokunmatik girişle mürekkep oluşturmayı sağlayan özel bir geçiş düğmesi tanımlayacağız (varsayılan olarak, dokunmatik mürekkep oluşturma etkin değildir).
Uyarı
Dokunmayla mürekkep oluşturmayı desteklemeniz gerekiyorsa, bu örnekte belirtilen simge ve araç ipucuyla birlikte CustomToggleButton kullanarak etkinleştirmenizi öneririz.
Dokunmatik giriş genellikle bir nesnenin veya uygulama kullanıcı arabiriminin doğrudan işlemesi için kullanılır. Dokunmatik mürekkep oluşturma etkinleştirildiğinde davranış farklılıklarını göstermek için, InkCanvas'ı bir ScrollViewer kapsayıcısına yerleştirir ve ScrollViewer'ın boyutlarını InkCanvas'tan daha küçük olacak şekilde ayarlarız.
Uygulama başlatıldığında, yalnızca kalemle mürekkep oluşturma desteklenir ve dokunma, mürekkep yüzeyini kaydırmak veya yakınlaştırmak için kullanılır. Dokunmatik mürekkep oluşturma etkinleştirildiğinde, mürekkep oluşturma yüzeyi dokunmatik giriş aracılığıyla kaydırılamaz veya yakınlaştırılamaz.
Uyarı
Bkz. Kalem kontrolleri için hem InkCanvas hem de InkToolbar UX yönergeleri. Aşağıdaki öneriler bu örnekle ilgilidir:
- InkToolbar ve genel olarak mürekkepleme, etkin kalemle en iyi deneyimlenir. Ancak, uygulamanız için gerekirse fare ve dokunma ile mürekkeple yazma özelliği desteklenebilir.
- Dokunmatik girişle mürekkep desteği sağlıyorsanız, "Dokunarak yazma" araç ipucuyla "Segoe MLD2 Assets" yazı tipindeki "ED5F" simgesini aç-kapa düğmesi için kullanmanızı öneririz.
XAML
- İlk olarak, olay işleyicisini (Toggle_Custom) belirten bir Click olayı dinleyicisi ile bir InkToolbarCustomToggleButton öğesi (toggleButton) tanımlarız.
<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>
Arka planda kod
Önceki kod parçacığında, dokunmatik kalemle yazma (toggleButton) için özelleştirilebilir geçiş düğmesinde Click olay dinleyicisi ve işleyicisi (Toggle_Custom) bildirdik. Bu işleyici, InkPresenter'ın InputDeviceTypes özelliği aracılığıyla CoreInputDeviceTypes.Touch desteğini değiştirir.
Ayrıca SymbolIcon öğesini ve arka planda kod dosyasında (TouchWritingIcon) tanımlanan bir alana bağlayan {x:Bind} işaretleme uzantısını kullanarak düğme için bir simge belirttik.
Aşağıdaki kod parçacığı hem Click olay işleyicisini hem de TouchWritingIcon tanımını içerir.
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;
}
}
}
}
Özel araç
Uygulamanız tarafından tanımlanan kalem olmayan bir aracı çağırmak için özel bir araç düğmesi oluşturabilirsiniz.
Varsayılan olarak, InkPresenter tüm girişleri mürekkep vuruşu veya silme vuruşu olarak işler. Buna kalem gövde düğmesi, sağ fare düğmesi veya benzer bir ikincil donanım öğesi tarafından değiştirilen girişler dahildir. Ancak InkPresenter , belirli girişleri işlenmemiş olarak bırakacak şekilde yapılandırılabilir ve bu işlem özel işlem için uygulamanıza geçirilebilir.
Bu örnekte, seçildiğinde sonraki vuruşların mürekkep yerine bir seçim kementi (kesikli çizgi) olarak işlenip görüntülenmesine neden olan özel bir araç düğmesi tanımlayacağız. Seçim alanının sınırları içindeki tüm mürekkep vuruşları Seçili olarak ayarlanır.
Uyarı
InkCanvas ve InkToolbar UX yönergeleri için mürekkep denetimlerine bakın. Aşağıdaki öneri bu örnekle ilgilidir:
- Vuruş seçimi sağlıyorsanız, araç düğmesi için "Segoe MLD2 Varlıkları" yazı tipindeki "EF20" simgesini bir "Seçim aracı" araç ipucuyla kullanmanızı öneririz.
XAML
İlk olarak, vuruş seçiminin yapılandırıldığı olay işleyicisini (customToolButton_Click) belirten Click olay dinleyicisi ile bir InkToolbarCustomToolButton öğesi (customToolButton) bildiririz. (Vuruş seçimini kopyalamak, kesmek ve yapıştırmak için bir dizi düğme de ekledik.)
Ayrıca, seçim vuruşumuzu çizebilmek için bir Canvas öğesi de ekleriz. Seçim vuruşunu çizmek için ayrı bir katman kullanmak, InkCanvas'in ve içeriğinin bozulmadan kalmasını sağlar.
<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>
Arka planda kod
Ardından MainPage.xaml.cs arka planda kod dosyasında InkToolbarCustomToolButton için Click olayını işleyeceğiz.
Bu işleyici , InkPresenter'ı işlememiş girişi uygulamaya geçirecek şekilde yapılandırır.
Daha ayrıntılı bir kod incelemesi için: Windows uygulamalarında Kalem etkileşimleri ve Windows Ink'in gelişmiş işleme bölümündeki Aktarım girişi kısmına bakın.
Ayrıca SymbolIcon öğesini ve bunu arka planda kod dosyasında tanımlanan bir alana bağlayan {x:Bind} işaretleme uzantısını (SelectIcon) kullanarak düğme için bir simge belirttik.
Aşağıdaki kod parçacığı hem Click olay işleyicisini hem de SelectIcon tanımını içerir.
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);
}
}
}
}
Özel mürekkep render'ı
Mürekkep girişi, varsayılan olarak düşük gecikme ile bir arka plan iş parçacığında işlenir ve çizilirken "ıslak" halde gösterilir. Vuruş tamamlandığında (kalem veya parmak kaldırıldığında veya fare düğmesi serbest bırakıldığında), vuruş kullanıcı arabirimi iş parçacığında işlenir ve InkCanvas katmanına "kuru" işlenir (uygulama içeriğinin üstünde ve ıslak milenk'in yerini alır).
Mürekkep platformu, mürekkep girdisini özel bir kurutma işlemi ile işleyerek bu davranışı geçersiz kılmanızı ve mürekkep işleme deneyimini tamamen özelleştirmenizi sağlar.
Özel kurutma hakkında daha fazla bilgi için bkz. Windows uygulamalarında Kalem etkileşimleri ve Windows Ink.
Uyarı
Özel kurutma ve InkToolbar
Uygulamanız özel bir kurutma uygulamasıyla InkPresenter'ın varsayılan mürekkep işleme davranışını geçersiz kılarsa, işlenen mürekkep vuruşları artık InkToolbar'da kullanılamaz ve InkToolbar'ın yerleşik silme komutları beklendiği gibi çalışmaz. Silme işlevselliği sağlamak için tüm işaretçi olaylarını işlemeniz, her vuruşta isabet testi gerçekleştirmeniz ve yerleşik "Tüm mürekkebleri sil" komutunu geçersiz kılmanız gerekir.
İlgili makaleler
Konu örnekleri
- Mürekkep araç çubuğu konumu ve yönlendirme örneği (temel)
- Mürekkep araç çubuğu konumu ve yönlendirme örneği (dinamik)
Diğer örnekler
Windows developer