WPF टेक्स्टब्लॉक को सेलेक्ट करने का कोई तरीका?


224

मैं पाठ को Witty में प्रदर्शित करना चाहता हूं , एक खुला स्रोत ट्विटर क्लाइंट, चयन करने योग्य। वर्तमान में यह एक कस्टम टेक्स्टब्लॉक का उपयोग करके प्रदर्शित किया गया है। मुझे टेक्स्टब्लॉक का उपयोग करने की आवश्यकता है, क्योंकि मैं @username और लिंक को हाइपरलिंक के रूप में प्रदर्शित करने और प्रारूपित करने के लिए टेक्स्टब्लॉक की इनलाइन के साथ काम कर रहा हूं। एक लगातार अनुरोध पाठ को कॉपी-पेस्ट करने में सक्षम होना है। ऐसा करने के लिए मुझे TextBlock को चयन करने योग्य बनाने की आवश्यकता है।

मैंने इसे टेक्स्टब्लॉक की तरह दिखने के लिए स्टाइल-ओनली टेक्स्टबॉक्स का उपयोग करके टेक्स्ट को प्रदर्शित करने के लिए काम करने की कोशिश की, लेकिन यह मेरे मामले में काम नहीं करेगा क्योंकि टेक्स्टबॉक्स में इनलाइन नहीं है। दूसरे शब्दों में, मैं टेक्स्टबॉक्स के भीतर पाठ को व्यक्तिगत रूप से स्टाइल या प्रारूपित नहीं कर सकता हूं जैसे मैं एक टेक्स्टब्लॉक के साथ कर सकता हूं।

कोई विचार?


1
मैं RichTextBox नियंत्रण का उपयोग करके देखने की कोशिश करूँगा कि क्या यह काम करेगा। लेकिन रिचटेक्स्टबॉक्स के साथ काम करने के पहले के अनुभव से बहुत अधिक जुड़े हुए हैं।
एलन ले

क्या आपने एक FlowDocumentScrollViewer का उपयोग करने के बारे में सोचा है, जिसमें फ़्लोडग्रोनमेंट जिसमें पैराग्राफ और रन शामिल हैं? - यह मेरे लिए बहुत अच्छा काम करता है जब मुझे चयन करने योग्य पाठ की आवश्यकता होती है, और प्रत्येक पैराग्राफ और रन को अलग से स्टाइल किया जा सकता है।
4S में ब्रेनस्ल्गस83

नीचे दिए गए कुछ वर्कअराउंड की कोशिश करने के बाद, फ़्लोडक्वामेंटमेंटस्क्रोल व्यूअर आगे का रास्ता था। यह RichTextBox और TextBlock के बीच एक उपयोगी मध्य मैदान पर कब्जा करने के लिए लगता है।
टॉम माकिन

नीचे एक जवाब स्वीकार करने के लिए वोट करें जो आपकी आवश्यकताओं के अनुरूप नहीं है।
ब्लेकडोज़

जवाबों:


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

6
मेरे पास एक प्रोजेक्ट है जिसमें कई TextBlocks / Labels हैं, मैं वास्तव में उन्हें TextBoxes में नहीं बदल सकता। मुझे क्या करना है, एप्लिकेशन-स्तरीय संसाधन में एक जादू लागू-से-सभी शैली जोड़ें ताकि यह सभी लेबल / टेक्स्टब्लॉक को प्रभावित करे, और उनके आंतरिक पाठ प्रस्तुतकर्ता को एक पठनीय टेक्स्टबॉक्स के रूप में बनाएं, क्या आपको किसी भी तरह से पता है इसे करने के लिए?
शिम्मी वेइटहैंडलर

5
आप अपनी स्थिति के आधार पर IsTabStop = "False" जोड़ना चाह सकते हैं
Karsten

1
+1 बहुत अच्छा समाधान! मैंने एक पैडिंग = "0" जोड़ा, क्योंकि मेरी परियोजना में पाठ का निचला भाग काट दिया गया था ... शायद एक शैली के कारण कहीं और।
reSPAWNed

123
-1 प्रश्न विशेष रूप से पूछता है कि टेक्स्टब्लॉक का चयन कैसे किया जाए। क्योंकि वह "इनलाइन" प्रॉपर्टी को खोना नहीं चाहता (जिसमें टेक्स्ट बॉक्स नहीं है)। यह 'उत्तर' सिर्फ एक टेक्स्टबॉक्स को टेक्स्टब्लॉक की तरह बनाने का सुझाव दे रहा है।
00jt

19
@AlanLe आपने यह उत्तर कब स्वीकार किया जब आपने स्पष्ट रूप से वही कहा जो आप नहीं चाहते थे? और 147 लोगों ने इसे क्यों उखाड़ फेंका?
जिम बेल्टर

66

यहां सभी उत्तर केवल 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इस कोड के प्रतिबिंब प्रतिबिंब का उपयोग करके किसी को अलग करने की आवश्यकता है :

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

1
आप एक और xaml के भीतर SelectableTextBlock वर्ग का उपयोग कैसे करेंगे जिसमें यह होना चाहिए?
योआव फुएर्स्टीन

1
उसी तरह आप किसी अन्य कस्टम नियंत्रण का उपयोग करेंगे। उदाहरण के लिए stackoverflow.com/a/3768178/332528 देखें
torvin

3
@BillyWilloughby आपका समाधान सिर्फ चयन का अनुकरण करता है। इसमें बहुत सारी मूल चयन सुविधाओं का अभाव है: कीबोर्ड समर्थन, संदर्भ मेनू आदि। मेरा समाधान मूल चयन सुविधा को सक्षम बनाता है
टोर्विन

3
ऐसा लगता है कि यह समाधान तब काम करता है जब तक एस TextBlockएम्बेडेड है जब तक कि इसमें अंतिम इनलाइन नहीं है। सामग्री में एक अनुगामी खाली जोड़ने से जो कुछ भी अंतर्निहित समस्या ठीक हो जाती है, उसका परिणाम यह होता है कि फेंक दिया जाता है। HyperlinkHyperlinkRunExecutionEngineException
एंटोन टायखी

2
यह भी खूब रही! सिवाय अगर आप TextTrimming="CharacterEllipsis"पर TextBlockऔर उपलब्ध चौड़ाई अपर्याप्त है, यदि आप उस पर माउस ले जाने के ..., यह System.ArgumentException साथ दुर्घटनाओं "अनुरोधित दूरी संबद्ध दस्तावेज़ की सामग्री के बाहर है।" System.Windows.Documents.TextPointer.InitializeOffset (TextPointer स्थिति, Int32 दूरी, LogicalDirection दिशा) :( पता नहीं है कि क्या वहाँ कोई और नहीं है, जबकि TextTrimming छोड़ने के अलावा कोई नहीं।
डेव हुआंग

32

मैं वास्तव में इस सवाल का जवाब देने के किसी भी उदाहरण को खोजने में असमर्थ रहा हूं। सभी उत्तरों में एक टेक्स्टबॉक्स या रिचटेक्स्टबॉक्स का उपयोग किया गया था। मुझे एक समाधान की आवश्यकता थी जिसने मुझे एक टेक्स्टब्लॉक का उपयोग करने की अनुमति दी, और यह वह समाधान है जो मैंने बनाया था।

मेरा मानना ​​है कि ऐसा करने का सही तरीका टेक्स्टब्लॉक क्लास का विस्तार करना है। यह वह कोड है जिसका उपयोग मैंने टेक्स्टब्लॉक क्लास को विस्तारित करने के लिए किया था ताकि मुझे टेक्स्ट का चयन करने और क्लिपबोर्ड पर कॉपी करने की अनुमति मिल सके। "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
यह स्वीकृत उत्तर होना चाहिए! कोई प्रतिबिंब हैक नहीं करता है, टेक्स्टबॉक्स का उपयोग नहीं कर रहा है ... और इसे आसानी से पुन: प्रयोज्य व्यवहार में बदला जा सकता है। बहुत अच्छा धन्यवाद!
थॉमस लेवेस्क

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 आज के रूप में, लेख के लिए लिंक मर गया लगता है
सुपरजोस

2
एक और इसके अलावा: पैडिंग -2,0, -2,0 होनी चाहिए। TextBox के अंदर, एक TextBoxView नियंत्रण बनाया जाता है जिसमें 2,0,2,0 का डिफ़ॉल्ट मार्जिन होता है। दुर्भाग्य से, आप इसकी शैली को फिर से परिभाषित नहीं कर सकते क्योंकि यह आंतरिक रूप से चिह्नित है।
fdub

11
कोई पढ़ नहीं पा रहा है। ओपी को एक टेक्स्टब्लॉक की आवश्यकता होती है, न कि टेक्स्टबॉक्स की तरह स्टाइल किए गए टेक्स्टबॉक्स की।
जिम बेल्टर

18

TextBlock के लिए ControlTemplate बनाएँ और आसानी से प्रॉपर्टी सेट के साथ एक TextBox अंदर रखें। या बस टेक्स्टबॉक्स का उपयोग करें और इसे आसानी से बनाएं, फिर आप टेक्स्ट बॉक्स को बदल सकते हैं।


11
आप TextBlock के लिए ControlTemplate कैसे सेट करते हैं? मुझे संपत्ति नहीं मिल रही है?
हेक्लेइट

18
यदि आपके TextBlock में इनलाइन तत्व हैं, तो यह दृष्टिकोण काम नहीं करेगा। यदि आपको हाइपरलिंक या बोल्ड या इटैलिक पाठ के रन मिल गए हों तो क्या होगा? टेक्स्टबॉक्स इनका समर्थन नहीं करता है।
दशरथ

1
यदि आप इनलाइन रन का उपयोग कर रहे हैं, तो यह काम नहीं करता है, और जैसे हैक्लाइट ने पूछा, मुझे यकीन नहीं है कि आप नियंत्रण टेम्पलेट से क्या मतलब है।
रिच मेल्टन

7
-1 TextBlock में ControlTemplate नहीं है क्योंकि यह FrameworkElement का प्रत्यक्ष उपवर्ग है। दूसरी ओर TextBox नियंत्रण का एक उपवर्ग है।
reSPAWNed

5
कोई क्यों नहीं पढ़ सकता है? ओपी ने स्पष्ट रूप से कहा कि एक टेक्स्टब्लॉक की जरूरत है, टेक्स्टबॉक्स की नहीं, क्योंकि टेक्स्टब्लॉक इनलाइन फॉर्मेटिंग का समर्थन करता है और टेक्स्टबॉक्स नहीं। क्यों इस तरह से पूरी तरह से गलत कचरा जवाब कई upvotes मिलता है?
जिम बेल्टर

10

मुझे यकीन नहीं है कि आप एक टेक्स्टब्लॉक का चयन कर सकते हैं, लेकिन एक अन्य विकल्प रिचटेक्स्टबॉक्स का उपयोग करना होगा - यह एक टेक्स्टबॉक्स की तरह है जैसा आपने सुझाव दिया था, लेकिन आप चाहते हैं कि स्वरूपण का समर्थन करता है।


1
मैंने ऐसा करने की कोशिश की, और इस प्रक्रिया में रिचटेक्स्टबॉक्स को एक निर्भरता संपत्ति के साथ बांधने योग्य बनाना था। दुर्भाग्य से पुराने flowdocuments ठीक से खारिज नहीं किया जा रहा है और स्मृति पागल की तरह लीक है। एलन, मुझे आश्चर्य है कि अगर आपको इसके चारों ओर एक रास्ता मिला?
जॉन नूनन

@ सभी प्रतिक्रियाओं का यहाँ अनुवाद करें, यह केवल दो में से एक है जो वास्तव में पूछे गए प्रश्न का उत्तर देता है ... अन्य सभी टेक्स्टबॉक्स की तरह दिखने के लिए टेक्स्ट बॉक्स स्टाइल करने की बात करते हैं, जबकि स्वरूपण की आवश्यकता को अनदेखा करते हैं। यह विचित्र, और दुर्भाग्यपूर्ण है, कि ओपी ने उन गैर-उत्तरों में से एक को स्वीकार किया, टेक्स्टबॉक्स के बजाय रिचटेक्स्टबॉक्स का उपयोग करने के लिए सही उत्तर के बजाय।
जिम बाल्टर

9

विंडोज देव केंद्र के अनुसार :

TextBlock.IsTextSelectionEnabled संपत्ति

[विंडोज पर UWP ऐप्स के लिए अपडेट किया गया। विंडोज 8.x लेखों के लिए, संग्रह देखें ]

हो जाता है या एक मूल्य इंगित करता है कि पाठ चयन में सक्षम है या नहीं सेट TextBlock , या तो उपयोगकर्ता कार्रवाई या चयन से संबंधित एपीआई बुला के माध्यम से।


5
दुर्भाग्य से, Win7 के साथ संगत नहीं है (कभी-कभी इसकी आवश्यकता होती है)
Yury Schkatula

24
Amswer गलत प्रतीत होता है। IsTextSelectionEnabled केवल UWP के लिए है, WPF के लिए नहीं - मूल प्रश्न WPF को निर्दिष्ट करता है।
पफिन

6

हालांकि प्रश्न 'चयन' कहता है, मेरा मानना ​​है कि टेक्स्ट को क्लिपबोर्ड पर लाने के लिए जानबूझकर परिणाम है। यह आसानी से और सुरुचिपूर्ण ढंग से एक प्रसंग मेनू और प्रतिलिपि नामक मेनू आइटम को जोड़कर प्राप्त किया जा सकता है, जो क्लिपबोर्ड में टेक्स्टब्लॉक पाठ गुण मान डालता है। वैसे भी सिर्फ एक विचार।


4

टेक्स्टब्लॉक का कोई टेम्प्लेट नहीं है। इसलिए इसे प्राप्त करने के लिए, हमें एक टेक्स्टबॉक्स का उपयोग करने की आवश्यकता है जिसकी शैली को टेक्स्टब्लॉक के रूप में व्यवहार करने के लिए बदल दिया गया है।

<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>

अन्य दृष्टिकोणों की तुलना में यह दृष्टिकोण क्या फायदे प्रदान करता है? मुझे कोई दिखाई नहीं देता।
सर्फ करें

मैंने इस शैली की कोशिश की: TextBoxBorder परिभाषित नहीं है। यदि आप इसे बाहर टिप्पणी करते हैं, तो यह ठीक काम करता है
शाम

यह उदाहरण कोड उत्कृष्ट है, यह दिखाता है कि टेक्स्टब्लॉक के लिए डिफ़ॉल्ट रंग कैसे प्राप्त करें।
कंटीनो

1
यह काफी उलझन भरा है। सबसे पहले, x: Key, "TextBlockUsingTextBoxStyle", पीछे की ओर है; यह "TextBoxUsingTextBlockStyle" होना चाहिए। दूसरा, ओपी पहले से ही जानता था कि टेक्स्टबॉक की तरह टेक्स्टबॉक्स कैसे स्टाइल करना है, लेकिन बार-बार कहा कि वह इसका उपयोग नहीं कर सकता क्योंकि उसे प्रारूपण के लिए इनलाइन की आवश्यकता थी।
जिम बेल्टर

2

एक वैकल्पिक समाधान है जो इस ब्लॉग पोस्ट में रिचटॉक्सबॉक्स के अनुकूलन के लिए अनुकूल हो सकता है - यह नियंत्रण टेम्पलेट को स्वैप करने के लिए ट्रिगर का उपयोग करता है जब उपयोग नियंत्रण पर हो जाता है - प्रदर्शन के साथ मदद करनी चाहिए


1
आपका लिंक मर चुका है। कृपया एक उत्तर के भीतर सभी प्रासंगिक जानकारी शामिल करें और केवल उद्धरण के रूप में लिंक का उपयोग करें।
जिम बाल्टर

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
यह मददगार नहीं है। ओपी वास्तव में क्या चाहता था यह देखने के लिए प्रश्न पढ़ें।
जिम बेल्टर

1

@ टोरिव के उत्तर और जैसा कि @Dave हुआंग ने टिप्पणी में उल्लेख किया है, यदि आपने एपलिप्सिस TextTrimming="CharacterEllipsis"पर मंडराने पर एप्लिकेशन क्रैश को सक्षम किया है।

मैंने टेक्स्टबॉक्स का उपयोग करने के बारे में धागे में उल्लिखित अन्य विकल्पों की कोशिश की, लेकिन यह वास्तव में समाधान नहीं लगता है क्योंकि यह 'दीर्घवृत्त' नहीं दिखाता है और यह भी कि यदि पाठ कंटेनर की सामग्री का चयन करने के लिए फिट होने के लिए बहुत लंबा है टेक्स्टबॉक्स 'स्क्रॉल' आंतरिक रूप से जो टेक्स्टब्लॉक व्यवहार नहीं है।

मुझे लगता है कि सबसे अच्छा समाधान @ टोरविन का जवाब है लेकिन दीर्घवृत्त दुर्घटनाग्रस्त हो गया है जब दीर्घवृत्त पर मंडराता है।

मुझे पता है कि यह सुंदर नहीं है, लेकिन सदस्यता समाप्त करने के लिए आंतरिक रूप से सदस्यता लेना / सदस्यता रद्द करना और अपवाद को संभालना एकमात्र तरीका था जो मुझे इस समस्या को हल करने का मिला, कृपया साझा करें यदि किसी के पास बेहतर समाधान है :)

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
यह सिर्फ एक टेक्स्टबॉक्स का उपयोग करता है, जैसे कई वर्षों से पहले कई अन्य उत्तर।
क्रिस


-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
एलेक्स होप ओ'कॉनर

लाइन 51 देता है: System.ArgumentNullException: 'मान शून्य नहीं हो सकता। पैरामीटर नाम: स्थिति 1 '
रोल करता है
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.