콘텐츠 링크는 사용자가 앱의 컨텍스트를 벗어나지 않고도 개인 또는 장소에 대한 자세한 정보를 찾고 사용할 수 있도록 텍스트 컨트롤에 풍부한 데이터를 포함하는 방법을 제공합니다.
중요합니다
콘텐츠 링크를 사용하도록 설정하는 Windows 기능은 Windows 10 버전 1903 이후의 Windows 버전에서는 사용할 수 없습니다. XAML 텍스트 컨트롤의 콘텐츠 링크는 버전 1903 이후 버전의 Windows에서 작동하지 않습니다.
사용자가 RichEditBox에서 at(@) 기호를 사용하여 항목 접두사를 지정하면 항목과 일치하는 사용자 목록 및/또는 제안 사항이 표시됩니다. 예를 들어 사용자가 위치를 선택하면 해당 위치에 대한 ContentLink가 텍스트에 삽입됩니다. 사용자가 RichEditBox에서 콘텐츠 링크를 호출하면 지도와 장소에 대한 추가 정보가 포함된 플라이아웃이 표시됩니다.
중요 API: ContentLink 클래스, ContentLinkInfo 클래스, RichEditTextRange 클래스
비고
콘텐츠 링크에 대한 API는 Windows.UI.Xaml.Controls, Windows.UI.Xaml.Documents 및 Windows.UI.Text 네임스페이스에 분산됩니다.
서식 있는 편집과 텍스트 블록 컨트롤의 콘텐츠 링크 비교
콘텐츠 링크를 사용하는 방법에는 두 가지가 있습니다.
- RichEditBox사용자는 선택기를 열어 @ 기호로 텍스트를 접두사로 지정하여 콘텐츠 링크를 추가할 수 있습니다. 콘텐츠 링크는 서식 있는 텍스트 콘텐츠의 일부로서 저장됩니다.
- TextBlock 또는 RichTextBlock에서, 콘텐츠 링크는 하이퍼링크와 유사한 사용 및 동작을 하는 텍스트 요소입니다.
다음은 RichEditBox 및 TextBlock에서 콘텐츠 링크가 기본적으로 표시되는 방식입니다.
서식 있는 편집 상자의 콘텐츠 링크 의 콘텐츠 링크
사용, 렌더링 및 동작의 차이점은 다음 섹션에서 자세히 설명합니다. 이 표에서는 RichEditBox의 콘텐츠 링크와 텍스트 블록 간의 주요 차이점을 간략하게 비교합니다.
특징 | 리치에디트박스 | 텍스트 블록 |
---|---|---|
사용법 | ContentLinkInfo 인스턴스 | ContentLink 텍스트 요소 |
커서 | 콘텐츠 링크 유형에 따라 결정되며 변경할 수 없습니다. | 커서 속성에 의해 결정되며, 기본적으로 null입니다. |
툴팁 | 렌더링되지 않음 | 보조 텍스트 표시 |
RichEditBox에서 콘텐츠 링크 사용
콘텐츠 링크의 가장 일반적인 용도는 사용자가 텍스트에 앰퍼샌드(@) 기호를 사용하여 사용자 또는 위치 이름을 접두사로 지정하여 정보를 빠르게 추가할 수 있도록 하는 것입니다. RichEditBox에서 사용하도록 설정하면 선택기가 열리고, 사용자가 활성화한 항목에 따라 연락처 목록에서 사람을 삽입하거나 가까운 위치를 선택할 수 있습니다.
콘텐츠 링크는 서식 있는 텍스트 콘텐츠와 함께 저장할 수 있으며, 추출하여 앱의 다른 부분에서 사용할 수 있습니다. 예를 들어 전자 메일 앱에서 사람 정보를 추출하고 이를 사용하여 전자 메일 주소로 To 상자를 채울 수 있습니다.
비고
콘텐츠 링크 선택기는 Windows의 일부인 앱이므로 앱과 별도의 프로세스로 실행됩니다.
콘텐츠 링크 공급자
RichEditBox.ContentLinkProviders 컬렉션에 하나 이상의 콘텐츠 링크 공급자를 추가하여 RichEditBox에서 콘텐츠 링크를 사용하도록 설정합니다. XAML 프레임워크에는 2개의 콘텐츠 링크 공급자가 기본 제공됩니다.
- ContactContentLinkProvider - 피플 앱을 사용하여 연락처를 조회합니다.
- PlaceContentLinkProvider – 지도 앱을 사용하여 위치를 조회합니다.
중요합니다
RichEditBox.ContentLinkProviders 속성의 기본값은 빈 컬렉션이 아니라 null입니다. 콘텐츠 링크 공급자를 추가하기 전에 ContentLinkProviderCollection 을 명시적으로 만들어야 합니다.
XAML에서 콘텐츠 링크 공급자를 추가하는 방법은 다음과 같습니다.
<RichEditBox>
<RichEditBox.ContentLinkProviders>
<ContentLinkProviderCollection>
<ContactContentLinkProvider/>
<PlaceContentLinkProvider/>
</ContentLinkProviderCollection>
</RichEditBox.ContentLinkProviders>
</RichEditBox>
스타일에 콘텐츠 링크 공급자를 추가하고 다음과 같이 여러 RichEditBox에 적용할 수도 있습니다.
<Page.Resources>
<Style TargetType="RichEditBox" x:Key="ContentLinkStyle">
<Setter Property="ContentLinkProviders">
<Setter.Value>
<ContentLinkProviderCollection>
<PlaceContentLinkProvider/>
<ContactContentLinkProvider/>
</ContentLinkProviderCollection>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<RichEditBox x:Name="RichEditBox01" Style="{StaticResource ContentLinkStyle}" />
<RichEditBox x:Name="RichEditBox02" Style="{StaticResource ContentLinkStyle}" />
코드에서 콘텐츠 링크 공급자를 추가하는 방법은 다음과 같습니다.
RichEditBox editor = new RichEditBox();
editor.ContentLinkProviders = new ContentLinkProviderCollection
{
new ContactContentLinkProvider(),
new PlaceContentLinkProvider()
};
콘텐츠 링크 색
콘텐츠 링크의 모양은 전경, 배경 및 아이콘에 따라 결정됩니다. RichEditBox에서 ContentLinkForegroundColor 및 ContentLinkBackgroundColor 속성을 설정하여 기본 색상을 변경할 수 있습니다.
커서를 설정할 수 없습니다. 커서는 리치에디트박스가 콘텐츠 링크의 종류에 따라 렌더링합니다. 사람 링크에는 사람 커서가, 장소 링크에는 핀 커서가 사용됩니다.
ContentLinkInfo 개체
사용자가 사람 또는 위치 선택기에서 선택을 하면, 시스템은 ContentLinkInfo 객체를 생성하고 이를 현재 RichEditTextRange의 ContentLinkInfo 속성에 추가합니다.
ContentLinkInfo 개체에는 콘텐츠 링크를 표시, 호출 및 관리하는 데 사용되는 정보가 포함되어 있습니다.
- DisplayText – 콘텐츠 링크가 렌더링될 때 표시되는 문자열입니다. RichEditBox에서 사용자는 만든 후 콘텐츠 링크의 텍스트를 편집하여 이 속성의 값을 변경할 수 있습니다.
-
SecondaryText – 이 문자열은 렌더링된 콘텐츠 링크의 도구 설명 표시됩니다.
- 선택기에서 만든 장소 콘텐츠 링크에는 사용 가능한 경우 위치의 주소가 포함됩니다.
- Uri – 콘텐츠 링크의 제목에 대한 자세한 정보 링크입니다. 이 URI는 설치된 앱 또는 웹 사이트를 열 수 있습니다.
- ID - RichEditBox 컨트롤에서 만든 컨트롤별 읽기 전용 카운터입니다. 삭제 또는 편집과 같은 작업 중에 이 ContentLinkInfo를 추적하는 데 사용됩니다. ContentLinkInfo를 잘라내어 컨트롤에 다시 붙여넣으면 새 ID가 표시됩니다. ID 값은 증분입니다.
- LinkContentKind – 콘텐츠 링크의 형식을 설명하는 문자열입니다. 기본 제공 콘텐츠 형식은 장소 및 연락처입니다. 값은 대/소문자를 구분합니다.
링크 콘텐츠 종류
LinkContentKind가 중요한 몇 가지 상황이 있습니다.
- 사용자가 RichEditBox에서 콘텐츠 링크를 복사하여 다른 RichEditBox에 붙여넣는 경우 두 컨트롤 모두 해당 콘텐츠 형식에 대한 ContentLinkProvider가 있어야 합니다. 그렇지 않을 경우 링크는 텍스트로 붙여넣어집니다.
- ContentLinkChanged 이벤트 처리기에서 LinkContentKind를 사용하여 콘텐츠 링크를 앱의 다른 부분에서 사용할 때 어떤 작업을 수행할지 결정할 수 있습니다. 자세한 내용은 예제 섹션을 참조하세요.
- LinkContentKind는 링크가 호출될 때 시스템에서 Uri를 여는 방법에 영향을 줍니다. 다음에 시작되는 Uri에 대한 논의에서 이 내용을 살펴보겠습니다.
Uri 실행
Uri 속성은 하이퍼링크의 NavigateUri 속성과 매우 유사합니다. 사용자가 클릭하면 URI가 기본 브라우저 또는 URI 값에 지정된 특정 프로토콜에 대해 등록된 앱에서 열립니다.
2가지 기본 제공 링크 콘텐츠의 특정 동작은 여기에 설명되어 있습니다.
장소들
위치 선택기는 https://maps.windows.com/을(를) Uri 루트로 하는 ContentLinkInfo를 생성합니다. 이 링크는 다음 세 가지 방법으로 열 수 있습니다.
- LinkContentKind = "Places"이면 플라이아웃에서 정보 카드가 열립니다. 플라이아웃은 콘텐츠 링크 선택 플라이아웃과 유사합니다. Windows의 일부이며 앱과 별도의 프로세스로 실행됩니다.
- LinkContentKind가 "장소"가 아닌 경우 Maps 앱을 지정된 위치로 열려고 시도합니다. 예를 들어 ContentLinkChanged 이벤트 처리기에서 LinkContentKind를 수정한 경우 이 오류가 발생할 수 있습니다.
- 지도 앱에서 URI를 열 수 없는 경우 기본 브라우저에서 맵이 열립니다. 일반적으로 사용자의 웹 사이트용 앱 설정에서 URI 열기를 Maps 앱으로 허용하지 않는 경우에 발생합니다.
사람
피플 선택기는 ms-people 프로토콜을 사용하는 URI를 사용하여 ContentLinkInfo를 만듭니다.
- LinkContentKind = "People"이면 플라이아웃에서 정보 카드가 열립니다. 플라이아웃은 콘텐츠 링크 선택 플라이아웃과 유사합니다. Windows의 일부이며 앱과 별도의 프로세스로 실행됩니다.
- LinkContentKind가 "People"이 아니면 People 앱이 열립니다. 예를 들어 ContentLinkChanged 이벤트 처리기에서 LinkContentKind를 수정한 경우 이 오류가 발생할 수 있습니다.
팁 (조언)
앱에서 다른 앱 및 웹 사이트를 여는 방법에 대한 자세한 내용은 Uri사용하여 앱 시작의 항목을 참조하세요.
호출
사용자가 콘텐츠 링크를 호출하면 Uri를 시작하는 기본 동작이 발생하기 전에 ContentLinkInvoked 이벤트가 발생합니다. 이 이벤트를 처리하여 기본 동작을 재정의하거나 취소할 수 있습니다.
이 예제에서는 장소 콘텐츠 링크에 대한 기본적인 실행 방식을 재정의하는 방법을 보여줍니다. 장소 정보 카드, 지도 앱 또는 기본 웹 브라우저에서 지도를 여는 대신 이벤트를 처리됨으로 표시하고 앱 내 WebView 컨트롤에서 맵을 엽니다.
<RichEditBox x:Name="editor"
ContentLinkInvoked="editor_ContentLinkInvoked">
<RichEditBox.ContentLinkProviders>
<ContentLinkProviderCollection>
<PlaceContentLinkProvider/>
</ContentLinkProviderCollection>
</RichEditBox.ContentLinkProviders>
</RichEditBox>
<WebView x:Name="webView1"/>
private void editor_ContentLinkInvoked(RichEditBox sender, ContentLinkInvokedEventArgs args)
{
if (args.ContentLinkInfo.LinkContentKind == "Places")
{
args.Handled = true;
webView1.Navigate(args.ContentLinkInfo.Uri);
}
}
콘텐츠 링크 변경됨
ContentLinkChanged 이벤트를 사용하여 콘텐츠 링크가 추가, 수정 또는 제거될 때 알림을 받을 수 있습니다. 이렇게 하면 텍스트에서 콘텐츠 링크를 추출하고 앱의 다른 위치에서 사용할 수 있습니다. 이 내용은 예제 섹션의 뒷부분에 나와 있습니다.
ContentLinkChangedEventArgs 속성은 다음과 같습니다.
- ChangedKind - 이 ContentLinkChangeKind 열거형(enum)은 ContentLink 내에서 수행되는 작업입니다. 예를 들어 ContentLink가 삽입, 제거 또는 편집되는 경우입니다.
- 정보 - 작업의 대상이었던 ContentLinkInfo입니다.
이 이벤트는 각 ContentLinkInfo 작업에 대해 발생합니다. 예를 들어 사용자가 여러 콘텐츠 링크를 복사하여 RichEditBox에 한 번에 붙여넣는 경우 이 이벤트는 추가된 각 항목에 대해 발생합니다. 또는 사용자가 여러 콘텐츠 링크를 동시에 선택하고 삭제하면 삭제된 각 항목에 대해 이 이벤트가 발생합니다.
이 이벤트는 TextChanging 이벤트 후 및 TextChanged 이벤트 전에 RichEditBox에서 발생합니다.
RichEditBox에서 콘텐츠 링크 나열
RichEditTextRange.ContentLink 속성을 사용하여 서식 있는 편집 문서에서 콘텐츠 링크를 가져올 수 있습니다. TextRangeUnit 열거형에는 콘텐츠 링크를 텍스트 범위를 탐색할 때 사용할 단위로 지정하는 ContentLink 값이 있습니다.
이 예제에서는 RichEditBox의 모든 콘텐츠 링크를 열거하고 사용자 목록을 추출하는 방법을 보여 줍니다.
<StackPanel Width="300">
<RichEditBox x:Name="Editor" Height="200">
<RichEditBox.ContentLinkProviders>
<ContentLinkProviderCollection>
<ContactContentLinkProvider/>
<PlaceContentLinkProvider/>
</ContentLinkProviderCollection>
</RichEditBox.ContentLinkProviders>
</RichEditBox>
<Button Content="Get people" Click="Button_Click"/>
<ListView x:Name="PeopleList" Header="People">
<ListView.ItemTemplate>
<DataTemplate x:DataType="ContentLinkInfo">
<TextBlock>
<ContentLink Info="{x:Bind}" Background="Transparent"/>
</TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
private void Button_Click(object sender, RoutedEventArgs e)
{
PeopleList.Items.Clear();
RichEditTextRange textRange = Editor.Document.GetRange(0, 0) as RichEditTextRange;
do
{
// The Expand method expands the Range EndPosition
// until it finds a ContentLink range.
textRange.Expand(TextRangeUnit.ContentLink);
if (textRange.ContentLinkInfo != null
&& textRange.ContentLinkInfo.LinkContentKind == "People")
{
PeopleList.Items.Add(textRange.ContentLinkInfo);
}
} while (textRange.MoveStart(TextRangeUnit.ContentLink, 1) > 0);
}
ContentLink 텍스트 요소
TextBlock 또는 RichTextBlock 컨트롤에서 콘텐츠 링크를 사용하려면 ContentLink 텍스트 요소(Windows.UI.Xaml.Documents 네임스페이스에서)를 사용합니다.
텍스트 블록의 ContentLink에 대한 일반적인 원본은 다음과 같습니다.
- RichTextBlock 컨트롤에서 추출한 선택기에서 만든 콘텐츠 링크입니다.
- 코드에서 생성한 장소에 대한 콘텐츠 링크입니다.
다른 상황에서는 일반적으로 하이퍼링크 텍스트 요소가 적절합니다.
ContentLink 외관
콘텐츠 링크의 모양은 전경, 배경 및 커서에 따라 결정됩니다. 텍스트 블록에서 전경(TextElement)을 설정하고 배경 속성을
기본적으로 손 커서는 사용자가 콘텐츠 링크를 마우스로 가리키면 표시됩니다. RichEditBlock과 달리 텍스트 블록 컨트롤은 링크 유형에 따라 커서를 자동으로 변경하지 않습니다. 커서 속성을 설정하여 링크 유형 또는 기타 요인에 따라 커서를 변경할 수 있습니다.
TextBlock에 사용되는 ContentLink의 예는 다음과 같습니다. ContentLinkInfo는 코드에서 만들어지고 XAML에서 만든 ContentLink 텍스트 요소의 Info 속성에 할당됩니다.
<StackPanel>
<TextBlock>
<Span xml:space="preserve">
<Run>This volcano erupted in 1980: </Run><ContentLink x:Name="placeContentLink" Cursor="Pin"/>
<LineBreak/>
</Span>
</TextBlock>
<Button Content="Show" Click="Button_Click"/>
</StackPanel>
private void Button_Click(object sender, RoutedEventArgs e)
{
var info = new Windows.UI.Text.ContentLinkInfo();
info.DisplayText = "Mount St. Helens";
info.SecondaryText = "Washington State";
info.LinkContentKind = "Places";
info.Uri = new Uri("https://maps.windows.com?cp=46.1912~-122.1944");
placeContentLink.Info = info;
}
팁 (조언)
텍스트 컨트롤에서 XAML의 다른 텍스트 요소와 함께 ContentLink를 사용하는 경우 콘텐츠를 Span 컨테이너에 배치하고 Span에 특성을 적용 xml:space="preserve"
하여 ContentLink와 다른 요소 사이에 공백을 유지합니다.
예시
이 예제에서는 사용자가 사람을 입력하거나 RickTextBlock에 콘텐츠 링크를 배치할 수 있습니다. ContentLinkChanged 이벤트를 처리하여 콘텐츠 링크를 추출하고, 사용자 목록이나 위치 목록에서 up-to-date로 업데이트된 상태로 유지합니다.
목록 항목의 템플릿에서 콘텐츠 링크 정보를 표시하기 위해 ContentLink 텍스트 구성 요소와 함께 TextBlock을 사용합니다. ListView는 각 항목에 대해 고유한 배경을 제공하므로 ContentLink 배경이 투명으로 설정됩니다.
<StackPanel Orientation="Horizontal" Grid.Row="1">
<RichEditBox x:Name="Editor"
ContentLinkChanged="Editor_ContentLinkChanged"
Margin="20" Width="300" Height="200"
VerticalAlignment="Top">
<RichEditBox.ContentLinkProviders>
<ContentLinkProviderCollection>
<ContactContentLinkProvider/>
<PlaceContentLinkProvider/>
</ContentLinkProviderCollection>
</RichEditBox.ContentLinkProviders>
</RichEditBox>
<ListView x:Name="PeopleList" Header="People">
<ListView.ItemTemplate>
<DataTemplate x:DataType="ContentLinkInfo">
<TextBlock>
<ContentLink Info="{x:Bind}"
Background="Transparent"
Cursor="Person"/>
</TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView x:Name="PlacesList" Header="Places">
<ListView.ItemTemplate>
<DataTemplate x:DataType="ContentLinkInfo">
<TextBlock>
<ContentLink Info="{x:Bind}"
Background="Transparent"
Cursor="Pin"/>
</TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
private void Editor_ContentLinkChanged(RichEditBox sender, ContentLinkChangedEventArgs args)
{
var info = args.ContentLinkInfo;
var change = args.ChangeKind;
ListViewBase list = null;
// Determine whether to update the people or places list.
if (info.LinkContentKind == "People")
{
list = PeopleList;
}
else if (info.LinkContentKind == "Places")
{
list = PlacesList;
}
// Determine whether to add, delete, or edit.
if (change == ContentLinkChangeKind.Inserted)
{
Add();
}
else if (args.ChangeKind == ContentLinkChangeKind.Removed)
{
Remove();
}
else if (change == ContentLinkChangeKind.Edited)
{
Remove();
Add();
}
// Add content link info to the list. It's bound to the
// Info property of a ContentLink in XAML.
void Add()
{
list.Items.Add(info);
}
// Use ContentLinkInfo.Id to find the item,
// then remove it from the list using its index.
void Remove()
{
var items = list.Items.Where(i => ((ContentLinkInfo)i).Id == info.Id);
var item = items.FirstOrDefault();
var idx = list.Items.IndexOf(item);
list.Items.RemoveAt(idx);
}
}
Windows developer