次の方法で共有


テキスト コントロールのコンテンツ リンク

コンテンツ リンクを使用すると、テキスト コントロールにリッチ データを埋め込むことができます。これにより、ユーザーはアプリのコンテキストを離れることなく、ユーザーが人や場所に関する詳細情報を見つけて使用できます。

Von Bedeutung

コンテンツ リンクを有効にする 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 の各名前空間に分散されます。

コンテンツ リンクを使用するには、次の 2 つの異なる方法があります。

  1. RichEditBox では、ユーザーはピッカーを開き、テキストの前に @ 記号を付けることでコンテンツ リンクを追加できます。 コンテンツ リンクは、リッチ テキスト コンテンツの一部として格納されます。
  2. TextBlock または RichTextBlock では、コンテンツ リンクはハイパーリンクと同様の使用法と動作を持つテキスト要素です。

RichEditBox と TextBlock のコンテンツ リンクの既定の外観を次に示します。

リッチ エディット ボックスのコンテンツ リンク テキスト ブロックのコンテンツ リンク

使用方法、レンダリング、動作の違いについては、次のセクションで詳しく説明します。 次の表では、RichEditBox のコンテンツ リンクとテキスト ブロックの主な違いを簡単に比較できます。

特徴 リッチエディットボックス テキストブロック
使用方法 ContentLinkInfo インスタンス ContentLink テキスト要素
カーソル コンテンツ リンクの種類によって決まる、変更できない Cursor プロパティによって決定され、既定で null
ツールヒント レンダリングされない セカンダリ テキストを表示する

コンテンツ リンクの最も一般的な用途は、ユーザーがテキストにアット (@) 記号を付けて人名や場所名を素早く追加することです。 RichEditBox で有効にすると、ピッカーが開き、ユーザーは、有効にした内容に応じて、連絡先リストまたは近くの場所からユーザーを挿入できます。

コンテンツ リンクはリッチ テキスト コンテンツと共に保存でき、それを抽出してアプリの他の部分で使用できます。 たとえば、メール アプリでは、ユーザー情報を抽出し、それを使用して [宛先] ボックスにメール アドレスを設定できます。

コンテンツ リンク ピッカーは Windows の一部であるアプリであるため、アプリとは別のプロセスで実行されます。

RichEditBox でコンテンツ リンクを有効にするには、1 つ以上のコンテンツ リンク プロバイダーを RichEditBox.ContentLinkProviders コレクションに追加します。 XAML フレームワークには、2 つのコンテンツ リンク プロバイダーが組み込まれています。

Von Bedeutung

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 では、ContentLinkForegroundColorContentLinkBackgroundColor のプロパティを設定して、既定の色を変更できます。

カーソルを設定することはできません。 カーソルは、コンテンツ リンクの種類 (人物リンクの 場合は Person カーソル、場所リンクの 場合はピン カーソル) に基づいて RichEditbox によってレンダリングされます。

ContentLinkInfo オブジェクト

ユーザーがユーザーまたは場所の選択ウィンドウから選択を行うと、システムによって ContentLinkInfo オブジェクトが作成され、現在の RichEditTextRangeContentLinkInfo プロパティに追加されます。

ContentLinkInfo オブジェクトには、コンテンツ リンクの表示、呼び出し、管理に使用される情報が含まれています。

  • DisplayText – コンテンツ リンクがレンダリングされるときに表示される文字列です。 RichEditBox では、ユーザーはコンテンツ リンクの作成後にテキストを編集できます。これにより、このプロパティの値が変更されます。
  • SecondaryText – この文字列は、レンダリングされたコンテンツ リンクの ヒント に表示されます。
    • ピッカーによって作成された [場所] コンテンツ リンクには、場所のアドレス (使用可能な場合) が含まれます。
  • Uri – コンテンツ リンクの件名に関する詳細情報へのリンク。 この URI は、インストールされているアプリまたは Web サイトを開くことができます。
  • 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 を作成します。 このリンクは、次の 3 つの方法で開くことができます。

  • LinkContentKind = "Places" の場合、ポップアップで情報カードが開きます。 ポップアップは、コンテンツ リンク ピッカーのポップアップに似ています。 これは Windows の一部であり、アプリとは別のプロセスで実行されます。
  • LinkContentKind が "Places" でない場合は、指定した場所に マップ アプリを開こうとします。 たとえば、これは、ContentLinkChanged イベント ハンドラーで LinkContentKind を変更した場合に発生する可能性があります。
  • マップ アプリで URI を開くことができない場合、マップは既定のブラウザーで開かれます。 これは通常、ユーザーの [Web サイト用アプリ] 設定で 、マップ アプリで URI を開くことができない場合に発生します。
人々

People ピッカーは、ms-people プロトコルを使用する URI を持つ ContentLinkInfo を作成します。

  • LinkContentKind = "People" の場合、ポップアップで情報カードが開きます。 ポップアップは、コンテンツ リンク ピッカーのポップアップに似ています。 これは Windows の一部であり、アプリとは別のプロセスで実行されます。
  • LinkContentKind が "People" でない場合は、 People アプリが開きます。 たとえば、これは、ContentLinkChanged イベント ハンドラーで LinkContentKind を変更した場合に発生する可能性があります。

ヒント

アプリから他のアプリや Web サイトを開く方法の詳細については、「Uri を使用して アプリを起動する」のトピックを参照してください。

呼び出さ れる

ユーザーがコンテンツ リンクを呼び出すと、Uri を起動する既定の動作が発生する前に ContentLinkInvoked イベントが発生します。 このイベントを処理して、既定の動作をオーバーライドまたは取り消すことができます。

この例では、Place コンテンツ リンクの既定の起動動作をオーバーライドする方法を示します。 場所情報カード、マップ アプリ、または既定の Web ブラウザーでマップを開く代わりに、イベントを Handled としてマークし、アプリ内 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 列挙型は ContentLink 内のアクションです。 たとえば、ContentLink が挿入、削除、または編集された場合です。
  • 情報 - アクションの対象となったContentLinkInfo。

このイベントは、ContentLinkInfo アクションごとに発生します。 たとえば、ユーザーが複数のコンテンツ リンクを一度にコピーして RichEditBox に貼り付けると、追加された項目ごとにこのイベントが発生します。 または、ユーザーが複数のコンテンツ リンクを同時に選択して削除すると、削除されたアイテムごとにこのイベントが発生します。

このイベントは、TextChanging イベントの後、TextChanged イベントの前に 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);
}

TextBlock または RichTextBlock コントロールでコンテンツ リンクを使用するには、(Windows.UI.Xaml.Documents 名前空間の ) ContentLink テキスト要素を使用します。

テキスト ブロック内の ContentLink の一般的なソースは次のとおりです。

  • RichTextBlock コントロールから抽出したピッカーによって作成されたコンテンツ リンク。
  • コードで作成する場所のコンテンツ リンク。

その他の状況では、通常、Hyperlink テキスト要素が適しています。

コンテンツ リンクの外観は、前景、背景、カーソルによって決まります。 テキスト ブロックでは、Foreground (TextElement から) プロパティと Background プロパティを設定して、既定の色を変更できます。

既定では、ユーザーがコンテンツ リンクの上にマウス ポインターを置くと 、ハンド カーソルが表示されます。 RichEditBlock とは異なり、テキスト ブロック コントロールはリンクの種類に基づいてカーソルを自動的に変更しません。 Cursor プロパティを設定すると、リンクの種類やその他の要因に基づいてカーソルを変更できます。

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 コンテナーに配置し、 xml:space="preserve" 属性を Span に適用して、ContentLink とその他の要素の間に空白を保持します。

例示

この例では、ユーザーはユーザーを入力したり、コンテンツ リンクを RickTextBlock に配置したりできます。 ContentLinkChanged イベントを処理してコンテンツ リンクを抽出し、ユーザー リストまたは場所リストに -date up-to保持します。

リストの項目テンプレートでは、ContentLink テキスト要素と共に TextBlock を使用してコンテンツ リンク情報を表示します。 ListView はアイテムごとに独自の背景を提供するため、ContentLink の背景は Transparent に設定されます。

<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);
    }
}