WPF 텍스트 블록을 선택 가능하게 만드는 방법은 무엇입니까?


224

오픈 소스 Twitter 클라이언트 인 Witty에 텍스트를 표시하도록 선택하고 싶습니다 . 현재 사용자 정의 텍스트 블록을 사용하여 표시됩니다. 텍스트 블록의 인라인을 사용하여 @username 및 링크를 하이퍼 링크로 표시하고 형식을 지정하기 때문에 TextBlock을 사용해야합니다. 자주 요청하면 텍스트를 복사하여 붙여 넣을 수 있습니다. 그렇게하려면 TextBlock을 선택 가능하게 만들어야합니다.

텍스트 블록처럼 보이도록 읽기 전용 TextBox를 사용하여 텍스트를 표시하여 작동 시키려고했지만 TextBox에 인라인이 없기 때문에 제 경우에는 작동하지 않습니다. 즉, TextBlock으로 할 수있는 것처럼 TextBox 내의 텍스트를 개별적으로 스타일을 지정하거나 서식을 지정할 수 없습니다.

어떤 아이디어?


1
RichTextBox 컨트롤을 사용하여 작동하는지 확인하겠습니다. 그러나 richtextbox를 사용한 경험이 훨씬 더 복잡합니다.
Alan Le

단락 및 실행이 포함 된 FlowDocument와 함께 FlowDocumentScrollViewer를 사용하는 것에 대해 생각해 보셨습니까? -이것은 선택 가능한 텍스트가 필요할 때 매우 잘 작동하며 각 단락과 실행은 개별적으로 스타일을 지정할 수 있습니다.
BrainSlugs83

아래의 해결 방법 중 일부를 시도한 후 FlowDocumentScrollViewer가 발전했습니다. RichTextBox와 TextBlock 사이의 유용한 중간 영역을 차지하는 것 같습니다.
Tom Makin

귀하의 요구 사항에 맞지 않는 답변을 수락 한 것에 대해 투표하십시오.
Blechdose

답변:


218
<TextBox Background="Transparent"
         BorderThickness="0"
         Text="{Binding Text, Mode=OneWay}"
         IsReadOnly="True"
         TextWrapping="Wrap" />

6
많은 TextBlocks / Labels가 포함 된 프로젝트가 있는데 실제로 TextBox로 바꿀 수 없습니다. 내가하고 싶은 것은 모든 레이블 / TextBlock에 영향을 미치고 내부 텍스트 발표자를 읽기 전용 TextBox로 만들어야하는 모든 응용 프로그램 수준의 리소스에 마법 적용 스타일을 추가하는 것입니다. 그것을하기 위해?
Shimmy Weitzhandler

5
상황에 따라 IsTabStop = "False"를 추가하고 싶을 수도 있습니다
Karsten

1
+1 아주 좋은 해결책! 내 프로젝트에서 텍스트 하단이 잘려서 Padding = "0"을 추가했습니다. 아마도 다른 곳의 스타일 때문일 것입니다.
reSPAWNed

123
-1 질문은 구체적으로 텍스트 블록을 선택 가능하게 만드는 방법을 묻습니다. 그는 "인라인"속성 (텍스트 상자에없는)을 잃고 싶지 않기 때문입니다. 이 '답변'은 텍스트 상자를 텍스트 블록처럼 보이게 만드는 것입니다.
00jt

19
@AlanLe 왜 당신이 원하지 않는다고 명시 적으로 말했을 때이 대답을 받아들였습니까? 그리고 왜 147 명의 단서없는 사람들이 그것을 찬성 했습니까?
Jim Balter

66

여기에있는 모든 대답은 a를 사용 TextBox하거나 텍스트 선택을 수동으로 구현하려고 시도하여 성능이 저하되거나 기본 동작이 아닙니다 (캐럿이 깜박이고 TextBox수동 구현에서 키보드가 지원되지 않음).

몇 시간 동안 WPF 소스 코드 를 파고 읽은 후 TextBlock컨트롤 (또는 실제로 다른 컨트롤)에 대한 기본 WPF 텍스트 선택을 활성화하는 방법을 발견했습니다 . 텍스트 선택과 관련된 대부분의 기능은 System.Windows.Documents.TextEditor시스템 클래스 에서 구현됩니다 .

컨트롤에서 텍스트를 선택하려면 두 가지 작업을 수행해야합니다.

  1. TextEditor.RegisterCommandHandlers()한 번만 호출 하여 클래스 이벤트 핸들러를 등록하십시오.

  2. TextEditor클래스의 각 인스턴스에 대한 인스턴스를 만들고 기본 인스턴스를 전달 System.Windows.Documents.ITextContainer하십시오.

컨트롤의 Focusable속성이로 설정되어 있어야 True합니다.

이거 야! 쉽게 들리지만 불행히도 TextEditor수업은 내부로 표시됩니다. 그래서 나는 그 주위에 반사 래퍼를 작성해야했습니다.

class TextEditorWrapper
{
    private static readonly Type TextEditorType = Type.GetType("System.Windows.Documents.TextEditor, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
    private static readonly PropertyInfo IsReadOnlyProp = TextEditorType.GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
    private static readonly PropertyInfo TextViewProp = TextEditorType.GetProperty("TextView", BindingFlags.Instance | BindingFlags.NonPublic);
    private static readonly MethodInfo RegisterMethod = TextEditorType.GetMethod("RegisterCommandHandlers", 
        BindingFlags.Static | BindingFlags.NonPublic, null, new[] { typeof(Type), typeof(bool), typeof(bool), typeof(bool) }, null);

    private static readonly Type TextContainerType = Type.GetType("System.Windows.Documents.ITextContainer, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
    private static readonly PropertyInfo TextContainerTextViewProp = TextContainerType.GetProperty("TextView");

    private static readonly PropertyInfo TextContainerProp = typeof(TextBlock).GetProperty("TextContainer", BindingFlags.Instance | BindingFlags.NonPublic);

    public static void RegisterCommandHandlers(Type controlType, bool acceptsRichContent, bool readOnly, bool registerEventListeners)
    {
        RegisterMethod.Invoke(null, new object[] { controlType, acceptsRichContent, readOnly, registerEventListeners });
    }

    public static TextEditorWrapper CreateFor(TextBlock tb)
    {
        var textContainer = TextContainerProp.GetValue(tb);

        var editor = new TextEditorWrapper(textContainer, tb, false);
        IsReadOnlyProp.SetValue(editor._editor, true);
        TextViewProp.SetValue(editor._editor, TextContainerTextViewProp.GetValue(textContainer));

        return editor;
    }

    private readonly object _editor;

    public TextEditorWrapper(object textContainer, FrameworkElement uiScope, bool isUndoEnabled)
    {
        _editor = Activator.CreateInstance(TextEditorType, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance, 
            null, new[] { textContainer, uiScope, isUndoEnabled }, null);
    }
}

또한 위에서 언급 한 단계를 수행 하는 SelectableTextBlock파생 제품을 만들었습니다 TextBlock.

public class SelectableTextBlock : TextBlock
{
    static SelectableTextBlock()
    {
        FocusableProperty.OverrideMetadata(typeof(SelectableTextBlock), new FrameworkPropertyMetadata(true));
        TextEditorWrapper.RegisterCommandHandlers(typeof(SelectableTextBlock), true, true, true);

        // remove the focus rectangle around the control
        FocusVisualStyleProperty.OverrideMetadata(typeof(SelectableTextBlock), new FrameworkPropertyMetadata((object)null));
    }

    private readonly TextEditorWrapper _editor;

    public SelectableTextBlock()
    {
        _editor = TextEditorWrapper.CreateFor(this);
    }
}

다른 옵션은 필요할 때 TextBlock텍스트를 선택할 수 있도록 연결된 속성을 만드는 것 입니다. 이 경우 선택을 다시 비활성화하려면 TextEditor이 코드와 동일한 리플렉션을 사용하여 a를 분리해야 합니다.

_editor.TextContainer.TextView = null;
_editor.OnDetach();
_editor = null;

1
그것을 포함 해야하는 다른 xaml 내에서 SelectableTextBlock 클래스를 어떻게 사용 하시겠습니까?
Yoav Feuerstein

1
다른 사용자 지정 컨트롤을 사용하는 것과 같은 방식으로. 예를 들어 stackoverflow.com/a/3768178/332528 참조
torvin

3
@BillyWhere는 솔루션이 선택을 에뮬레이트합니다. 키보드 지원, 컨텍스트 메뉴 등 내 솔루션은 기본 선택 기능 수 있습니다 : 그것은 기본 선택 기능이 많이 부족
Torvin 사용자

3
이 솔루션 것 같다 않습니다 (가) 때 일을 TextBlock내장 한 Hyperlink만큼이 같은의를 Hyperlink그것의 마지막 인라인하지 않습니다. Run내용에 후행 공백 을 추가하면 발생하는 근본적인 문제가 무엇이든 해결 ExecutionEngineException됩니다.
Anton Tykhyy

2
대단해! 당신이있는 경우를 제외하고 TextTrimming="CharacterEllipsis"상의 TextBlock하고 위에 마우스 포인터를 이동하는 경우 사용할 수있는 폭이 불충분 ..., 그것은 System.ArgumentException와 충돌 "요청 된 거리가 관련 문서의 내용 밖에 있습니다." at System.Windows.Documents.TextPointer.InitializeOffset (TextPointer 위치, Int32 거리, LogicalDirection 방향) :( TextTrimming을 None으로 설정하지 않고 다른 해결 방법이 있는지 모릅니다
Dave Huang

32

나는 그 질문에 실제로 대답하는 예를 찾지 못했습니다. 모든 답변은 텍스트 상자 또는 RichTextbox를 사용했습니다. TextBlock을 사용할 수있는 솔루션이 필요했으며 이것이 내가 만든 솔루션입니다.

올바른 방법은 TextBlock 클래스를 확장하는 것입니다. 이것은 텍스트를 선택하고 클립 보드에 복사 할 수 있도록 TextBlock 클래스를 확장하는 데 사용한 코드입니다. "sdo"는 WPF에서 사용한 네임 스페이스 참조입니다.

확장 클래스를 사용하는 WPF :

xmlns:sdo="clr-namespace:iFaceCaseMain"

<sdo:TextBlockMoo x:Name="txtResults" Background="Black" Margin="5,5,5,5" 
      Foreground="GreenYellow" FontSize="14" FontFamily="Courier New"></TextBlockMoo>

확장 클래스를위한 코드 숨김 :

public partial class TextBlockMoo : TextBlock 
{
    TextPointer StartSelectPosition;
    TextPointer EndSelectPosition;
    public String SelectedText = "";

    public delegate void TextSelectedHandler(string SelectedText);
    public event TextSelectedHandler TextSelected;

    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);
        Point mouseDownPoint = e.GetPosition(this);
        StartSelectPosition = this.GetPositionFromPoint(mouseDownPoint, true);            
    }

    protected override void OnMouseUp(MouseButtonEventArgs e)
    {
        base.OnMouseUp(e);
        Point mouseUpPoint = e.GetPosition(this);
        EndSelectPosition = this.GetPositionFromPoint(mouseUpPoint, true);

        TextRange otr = new TextRange(this.ContentStart, this.ContentEnd);
        otr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.GreenYellow));

        TextRange ntr = new TextRange(StartSelectPosition, EndSelectPosition);
        ntr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.White));

        SelectedText = ntr.Text;
        if (!(TextSelected == null))
        {
            TextSelected(SelectedText);
        }
    }
}

창 코드 예 :

    public ucExample(IInstanceHost host, ref String WindowTitle, String ApplicationID, String Parameters)
    {
        InitializeComponent();
        /*Used to add selected text to clipboard*/
        this.txtResults.TextSelected += txtResults_TextSelected;
    }

    void txtResults_TextSelected(string SelectedText)
    {
        Clipboard.SetText(SelectedText);
    }

1
이것이 정답입니다! TextBox를 사용하지 않는 리플렉션 해킹이 없으며 재사용 가능한 동작으로 쉽게 리팩터링 될 수 있습니다. 고마워요!
토마스 레베 스크

19

이 스타일을 TextBox에 적용하면됩니다 ( 이 기사 에서 영감을 얻음 ).

<Style x:Key="SelectableTextBlockLikeStyle" TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="IsReadOnly" Value="True"/>
    <Setter Property="IsTabStop" Value="False"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Padding" Value="-2,0,0,0"/>
    <!-- The Padding -2,0,0,0 is required because the TextBox
        seems to have an inherent "Padding" of about 2 pixels.
        Without the Padding property,
        the text seems to be 2 pixels to the left
        compared to a TextBlock
    -->
    <Style.Triggers>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsMouseOver" Value="False" />
                <Condition Property="IsFocused" Value="False" />
            </MultiTrigger.Conditions>
            <Setter Property="Template">
                <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <TextBlock Text="{TemplateBinding Text}" 
                             FontSize="{TemplateBinding FontSize}"
                             FontStyle="{TemplateBinding FontStyle}"
                             FontFamily="{TemplateBinding FontFamily}"
                             FontWeight="{TemplateBinding FontWeight}"
                             TextWrapping="{TemplateBinding TextWrapping}"
                             Foreground="{DynamicResource NormalText}"
                             Padding="0,0,0,0"
                                       />
                </ControlTemplate>
                </Setter.Value>
            </Setter>
        </MultiTrigger>
    </Style.Triggers>
</Style>

1
BTW 오늘의로, 기사 링크가 죽은 것 같다
superjos에게

2
또 다른 추가 사항 : 패딩은 -2,0, -2,0이어야합니다. TextBox 안에 기본 여백이 2,0,2,0 인 TextBoxView 컨트롤이 만들어집니다. 불행히도 스타일은 내부로 표시되어 있기 때문에 스타일을 다시 정의 할 수 없습니다.
fdub

11
아무도 읽을 수없는 것 같습니다. OP에는 TextBlock과 같은 스타일의 TextBox가 아닌 TextBlock이 필요합니다.
Jim Balter

18

TextBlock에 대한 ControlTemplate을 만들고 읽기 전용 속성이 설정된 TextBox를 넣습니다. 또는 TextBox를 사용하여 읽기 전용으로 만든 다음 TextBox.Style을 TextBlock처럼 보이도록 변경할 수 있습니다.


11
TextBlock에 대한 ControlTemplate을 어떻게 설정합니까? 속성을 찾을 수 없습니까?
HaxElit

18
TextBlock에 인라인 요소가 있으면이 방법이 작동하지 않습니다. 하이퍼 링크 나 굵은 기울임 꼴 또는 기울임 꼴 텍스트가있는 경우 어떻게해야합니까? TextBox는이를 지원하지 않습니다.
dthrasher

1
인라인 실행을 사용하는 경우 작동하지 않으며 HaxElit이 요청한 것처럼 컨트롤 템플릿의 의미가 무엇인지 잘 모르겠습니다.
Ritch Melton

7
-1 TextBlock에는 FrameworkElement의 직접적인 하위 클래스이므로 ControlTemplate이 없습니다. 반면 TextBox는 Control의 하위 클래스입니다.
reSPAWNed

5
왜 아무도 읽을 수 없습니까? OP는 TextBlock이 인라인 형식을 지원하고 TextBox는 지원하지 않기 때문에 TextBox가 아닌 TextBlock이 필요하다고 명시 적으로 말했습니다. 이와 같은 잘못된 가비지 응답이 왜 수많은 공감대를 얻습니까?
Jim Balter

10

TextBlock을 선택할 수 있는지 확실하지 않지만 다른 옵션은 RichTextBox를 사용하는 것입니다. 제안한 TextBox와 비슷하지만 원하는 형식을 지원합니다.


1
나는 이것을 시도했고, 그 과정에서 RichTextBox를 의존성 속성과 바인딩 가능하게 만들어야했다. 불행히도 오래된 플로우 문서는 올바르게 폐기되지 않고 메모리가 미친 것처럼 누출됩니다. 앨런,이 문제를 해결할 방법이 있는지 궁금 하신가요?
John Noonan

@AlanLe 여기에있는 모든 대답 중 이것은 실제로 묻는 질문에 대답하는 두 가지 중 하나입니다 ... 다른 사람들은 모두 TextBlock처럼 보이도록 TextBox의 스타일을 지정하는 동시에 형식 지정의 필요성을 무시합니다. OP가 TextBox 대신 RichTextBox를 사용하는 정답 대신 이러한 비 응답 중 하나를 수락 한 것이 기이하고 불행한 일입니다.
Jim Balter

9

에 따르면 윈도우 개발자 센터 :

TextBlock.IsTextSelectionEnabled 속성

[Windows 10의 UWP 앱용으로 업데이트되었습니다. Windows 8.x 문서의 경우 아카이브를 참조하십시오. ]

사용자 작업 또는 선택 관련 API 호출을 통해 TextBlock 에서 텍스트 선택이 활성화되어 있는지 여부를 나타내는 값을 가져 오거나 설정합니다 .


5
불행히도, Win7과 호환되지 않습니다 (때로는 필수 조건 임)
Yury Schkatula

24
Amswer가 잘못 나타납니다. IsTextSelectionEnabled는 WPF가 아닌 UWP에만 해당됩니다. 원래 질문에서 WPF를 지정했습니다.
Puffin

6

질문에 '선택 가능'이라고 표시되어 있지만 의도적 인 결과는 텍스트를 클립 보드로 가져 오는 것입니다. Textblock Text 속성 값을 클립 보드에 넣는 컨텍스트 메뉴와 copy라는 메뉴 항목을 추가하면 쉽고 우아하게 얻을 수 있습니다. 어쨌든 아이디어.


4

TextBlock에는 템플릿이 없습니다. 이를 위해 스타일이 textBlock으로 동작하도록 변경된 TextBox를 사용해야합니다.

<Style x:Key="TextBlockUsingTextBoxStyle" BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Padding" Value="1"/>
    <Setter Property="AllowDrop" Value="true"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
    <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <TextBox BorderThickness="{TemplateBinding BorderThickness}" IsReadOnly="True" Text="{TemplateBinding Text}" Background="{x:Null}" BorderBrush="{x:Null}" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

이 방법은 다른 답변과 비교하여 어떤 이점을 제공합니까? 나는 보이지 않는다.
surfen

이 스타일을 시도했습니다 : TextBoxBorder가 정의되지 않았습니다. 당신이 그것을 주석 경우, 그것을 잘 작동합니다
sthiers에게

이 예제 코드는 훌륭하며 TextBlock의 기본 색상을 얻는 방법을 보여줍니다.
Contango

1
이것은 매우 혼란 스럽다. 먼저 x : Key 인 "TextBlockUsingTextBoxStyle"이 거꾸로되어 있습니다. "TextBoxUsingTextBlockStyle"이어야합니다. 둘째, OP는 이미 TextBlock과 같은 TextBox의 스타일을 지정하는 방법을 알고 있었지만 서식을 위해 인라인이 필요하기 때문에 사용할 수 없다고 반복해서 말했습니다.
Jim Balter

2

블로그 게시물 에서 부인 한 RichTextBox에 적용 할 수있는 대체 솔루션이 있습니다 . 사용이 컨트롤을 가리킬 때 트리거를 사용하여 컨트롤 템플릿을 교체하면 성능에 도움이됩니다.


1
연결이 끊어졌습니다. 답변에 모든 관련 정보를 포함시키고 인용으로 만 링크를 사용하십시오.
Jim Balter

1

new TextBox
{
   Text = text,
   TextAlignment = TextAlignment.Center,
   TextWrapping = TextWrapping.Wrap,
   IsReadOnly = true,
   Background = Brushes.Transparent,
   BorderThickness = new Thickness()
         {
             Top = 0,
             Bottom = 0,
             Left = 0,
             Right = 0
         }
};


1
도움이되지 않습니다. OP가 실제로 원하는 것을 보려면 질문을 읽으십시오.
Jim Balter

1

TextTrimming="CharacterEllipsis"줄임표 위로 마우스를 가져 가면 응용 프로그램 이 활성화 된 경우 @torvin의 답변에 추가하고 @Dave Huang이 주석에 언급 한 것처럼 .

스레드에서 TextBox 사용에 대해 언급 한 다른 옵션을 시도했지만 '줄임표'를 표시하지 않고 텍스트가 너무 길어 컨테이너를 내용을 선택하기에 너무 길면 해결책이 아닌 것 같습니다. TextBlock 동작이 아닌 텍스트 상자가 내부적으로 '스크롤'됩니다.

최선의 해결책은 @torvin의 대답이라고 생각하지만 줄임표 위로 마우스를 가져 가면 심한 충돌이 발생합니다.

나는 그것이 예쁘지 않다는 것을 알고 있지만 처리되지 않은 예외를 내부적으로 구독 / 구독 취소하고 예외를 처리하는 것이이 문제를 해결하는 유일한 방법이었습니다. 누군가 더 나은 해결책을 가지고 있다면 공유하십시오 :)

public class SelectableTextBlock : TextBlock
{
    static SelectableTextBlock()
    {
        FocusableProperty.OverrideMetadata(typeof(SelectableTextBlock), new FrameworkPropertyMetadata(true));
        TextEditorWrapper.RegisterCommandHandlers(typeof(SelectableTextBlock), true, true, true);

        // remove the focus rectangle around the control
        FocusVisualStyleProperty.OverrideMetadata(typeof(SelectableTextBlock), new FrameworkPropertyMetadata((object)null));
    }

    private readonly TextEditorWrapper _editor;

    public SelectableTextBlock()
    {
        _editor = TextEditorWrapper.CreateFor(this);

        this.Loaded += (sender, args) => {
            this.Dispatcher.UnhandledException -= Dispatcher_UnhandledException;
            this.Dispatcher.UnhandledException += Dispatcher_UnhandledException;
        };
        this.Unloaded += (sender, args) => {
            this.Dispatcher.UnhandledException -= Dispatcher_UnhandledException;
        };
    }

    private void Dispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
    {
        if (!string.IsNullOrEmpty(e?.Exception?.StackTrace))
        {
            if (e.Exception.StackTrace.Contains("System.Windows.Controls.TextBlock.GetTextPositionFromDistance"))
            {
                e.Handled = true;
            }
        }
    }
}

0

오픈 소스 컨트롤 라이브러리에서 SelectableTextBlock 을 구현했습니다 . 다음과 같이 사용할 수 있습니다.

<jc:SelectableTextBlock Text="Some text" />

4
이것은 몇 년 전의 많은 다른 답변과 마찬가지로 TextBox 만 사용합니다.
Chris

0
public MainPage()
{
    this.InitializeComponent();
    ...
    ...
    ...
    //Make Start result text copiable
    TextBlockStatusStart.IsTextSelectionEnabled = true;
}

-1
Really nice and easy solution, exactly what I wanted !

약간의 수정을 가져옵니다

public class TextBlockMoo : TextBlock 
{
    public String SelectedText = "";

    public delegate void TextSelectedHandler(string SelectedText);
    public event TextSelectedHandler OnTextSelected;
    protected void RaiseEvent()
    {
        if (OnTextSelected != null){OnTextSelected(SelectedText);}
    }

    TextPointer StartSelectPosition;
    TextPointer EndSelectPosition;
    Brush _saveForeGroundBrush;
    Brush _saveBackGroundBrush;

    TextRange _ntr = null;

    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);

        if (_ntr!=null) {
            _ntr.ApplyPropertyValue(TextElement.ForegroundProperty, _saveForeGroundBrush);
            _ntr.ApplyPropertyValue(TextElement.BackgroundProperty, _saveBackGroundBrush);
        }

        Point mouseDownPoint = e.GetPosition(this);
        StartSelectPosition = this.GetPositionFromPoint(mouseDownPoint, true);            
    }

    protected override void OnMouseUp(MouseButtonEventArgs e)
    {
        base.OnMouseUp(e);
        Point mouseUpPoint = e.GetPosition(this);
        EndSelectPosition = this.GetPositionFromPoint(mouseUpPoint, true);

        _ntr = new TextRange(StartSelectPosition, EndSelectPosition);

        // keep saved
        _saveForeGroundBrush = (Brush)_ntr.GetPropertyValue(TextElement.ForegroundProperty);
        _saveBackGroundBrush = (Brush)_ntr.GetPropertyValue(TextElement.BackgroundProperty);
        // change style
        _ntr.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Colors.Yellow));
        _ntr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.DarkBlue));

        SelectedText = _ntr.Text;
    }
}

1
아래 답변에서 변경 한 내용을 설명해야합니다. -1
Alex Hope O'Connor

51 행은 System.ArgumentNullException : '값은 null 일 수 없습니다. 매개 변수 이름 : position1 '
롤링
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.