Skip to content

CustomEditControl Sample: WinAppSDK Edition #195

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ This repository hosts samples for the [Windows App SDK](https://github.com/micro
- [Push Notifications](Samples/Notifications/Push): This is a sample app that showcases Push Notifications.

#### User Interface and Input
- [CustomEditControl](Samples/CustomEditControl): This sample demonstrates how to create a text edit control with customized UI and behavior.
- [Windowing](Samples/Windowing): This sample demonstrates how to manage app windows using the Windowing APIs.
- [Windows Input and Composition Gallery](https://github.com/microsoft/WindowsCompositionSamples): This collection of samples showcases Microsoft.UI.Composition and Microsoft.UI.Input APIs.
- [XAML Controls Gallery](https://github.com/microsoft/Xaml-Controls-Gallery/tree/winui3): This is a sample app that showcases all of the WinUI 3 controls in action.
Expand Down
94 changes: 94 additions & 0 deletions Samples/CustomEditControl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
page_type: sample
languages:
- csharp
- cppwinrt
- cpp
products:
- windows
- windows-app-sdk
name: "Custom Edit Control"
urlFragment: CustomEditControl
description: "Shows how to use the CoreTextEditContext class to create a rudimentary text control."
extendedZipContent:
- path: LICENSE
target: LICENSE
---

# Custom Edit Control sample

Shows how to use the CoreTextEditContext class in the Windows.UI.Text.Core namespace
to create a rudimentary text control. Note that this text control is not complete;
it glosses over many details that would be necessary for a complete text edit control.

The focus of the sample is in CustomEditControl to show how to implement and manage a text control.
There is much more functionality built in to the CoreTextEditContext that is not covered in this sample.

This sample demonstrates the following:

* Managing the text and current selection of a custom edit control.
This sample uses a simple string to record the text.
* Rendering the text and current selection in the custom edit control.
To illustrate that the app is completely responsible for the visual
presentation of the control, this sample takes the unusual decision
to use a globe to represent the caret.
* Manually setting focus to and removing focus from the control
and the CoreTextEditContext based on application-defined criteria.
The CoreTextEditContext processes text input when it has focus.
* Setting the CoreTextEditContext.InputPaneDisplayPolicy to Manual
and manually showing the software keyboard when the custom edit control
gains focus and hiding it when the custom edit control loses focus.
* Responding to system events that request information about the
custom edit control or request changes to the text and selection of
the custom edit control.
* Responding to layout information requests so that the IME candidate window
can be positioned properly.
* Changing the selection and/or moving the caret when the user presses
an arrow key, and deleting text when the user presses the Backspace key.

**Instructions on using this sample**

* Click or tap on the custom edit control to give it focus,
and click or tap outside the custom edit control to remove focus.
* Observe that the Input Pane appears (if applicable)
when the custom edit control gains focus,
and it disappears when the custom edit control loses focus.
* Use the arrow keys to move the caret (shown as a globe).
* Hold the shift key when pressing the arrow keys to adjust
the selection.
* Use the Backspace key to delete text.
* To demonstrate support for IME candidates:
* Install an IME by going to Settings, Time and Language,
Region and language. Click "Add a language" and select
Chinese (Simplified) "中文(中华人民共和国)".
* Set your input language to Chinese by using the language
selector in the bottom right corner of the taskbar (on Desktop)
or by swiping the space bar on the software keyboard (on Mobile).
* Put focus on the custom edit control and start typing.
IME candidate suggestions will appear as you type.

**Features missing from this sample**

* This sample does not properly handle surrogate pairs
or grapheme clusters.
* This sample does not support common keyboard shortcuts
such as Home and End, nor does it support shortcuts such
as Ctrl+V to paste.
* This sample does not show a context menu if the user right-clicks
or performs a press-and-hold gesture.
* This sample does not support using the mouse or touch to
move the caret or adjust the selection.

## Prerequisites

* See [System requirements for Windows app development](https://docs.microsoft.com/windows/apps/windows-app-sdk/system-requirements).
* Make sure that your development environment is set up correctly—see [Install tools for developing apps for Windows 10 and Windows 11](https://docs.microsoft.com/windows/apps/windows-app-sdk/set-up-your-development-environment).

## Building and running any of the samples

* Open the solution file (`.sln`) from the subfolder of your preferred sample in Visual Studio.
* From Visual Studio, either **Start Without Debugging** (Ctrl+F5) or **Start Debugging** (F5).

## Related Links

- [CoreTextEditContext](https://msdn.microsoft.com/library/windows/apps/windows.ui.text.core.coretexteditcontext.aspx)
6 changes: 6 additions & 0 deletions Samples/CustomEditControl/cpp-winui/App.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

namespace CustomEditControlCpp
{
}
18 changes: 18 additions & 0 deletions Samples/CustomEditControl/cpp-winui/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!-- Copyright (c) Microsoft Corporation.
Licensed under the MIT License. -->

<Application
x:Class="CustomEditControlCpp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CustomEditControlCpp">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Other merged dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->
</ResourceDictionary>
</Application.Resources>
</Application>
49 changes: 49 additions & 0 deletions Samples/CustomEditControl/cpp-winui/App.xaml.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#include "pch.h"

#include "App.xaml.h"
#include "MainWindow.xaml.h"

using namespace winrt;
using namespace Windows::Foundation;
using namespace Microsoft::UI::Xaml;
using namespace Microsoft::UI::Xaml::Controls;
using namespace Microsoft::UI::Xaml::Navigation;
using namespace CustomEditControlCpp;
using namespace CustomEditControlCpp::implementation;

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.

/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
App::App()
{
InitializeComponent();

#if defined _DEBUG && !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException([this](IInspectable const&, UnhandledExceptionEventArgs const& e)
{
if (IsDebuggerPresent())
{
auto errorMessage = e.Message();
__debugbreak();
}
});
#endif
}

/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
void App::OnLaunched(LaunchActivatedEventArgs const&)
{
window = make<MainWindow>();
window.Activate();
}
19 changes: 19 additions & 0 deletions Samples/CustomEditControl/cpp-winui/App.xaml.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#pragma once

#include "App.xaml.g.h"

namespace winrt::CustomEditControlCpp::implementation
{
struct App : AppT<App>
{
App();

void OnLaunched(Microsoft::UI::Xaml::LaunchActivatedEventArgs const&);

private:
winrt::Microsoft::UI::Xaml::Window window{ nullptr };
};
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions Samples/CustomEditControl/cpp-winui/CustomEditControl.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

namespace CustomEditControlCpp
{
[default_interface]
runtimeclass CustomEditControl : Microsoft.UI.Xaml.Controls.UserControl
{
CustomEditControl();
void SetAppWindow(Microsoft.UI.WindowId windowId);
void SetInternalFocus();
void RemoveInternalFocus();
}
}
37 changes: 37 additions & 0 deletions Samples/CustomEditControl/cpp-winui/CustomEditControl.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!-- Copyright (c) Microsoft Corporation.
Licensed under the MIT License. -->

<UserControl
x:Class="CustomEditControlCpp.CustomEditControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CustomEditControlCpp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="30"
d:DesignWidth="400"
AllowFocusOnInteraction="True"
IsHitTestVisible="True"
IsEnabled="True"
IsTabStop="True">

<StackPanel>
<!-- Our custom edit control -->
<StackPanel x:Name="BorderPanel" BorderThickness="4" Background="White">
<StackPanel x:Name="ContentPanel" Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock x:Name="BeforeSelectionText" Foreground="Black"/>
<TextBlock x:Name="CaretText" Text="&#xe12b;" Foreground="Blue" FontFamily="Segoe UI Symbol"/>
<Border Background="Blue">
<TextBlock x:Name="SelectionText" Foreground="White"/>
</Border>
<TextBlock x:Name="AfterSelectionText" Foreground="Black"/>
</StackPanel>
</StackPanel>
<!-- Additional statistics for demonstration purposes -->
<TextBlock>Full text: <Run x:Name="FullText"/></TextBlock>
<TextBlock>Selection start index: <Run x:Name="SelectionStartIndexText"/></TextBlock>
<TextBlock>Selection end index: <Run x:Name="SelectionEndIndexText"/></TextBlock>
<!-- <TextBox Height="30" Width="400"></TextBox> -->
</StackPanel>
</UserControl>
Loading