2009-07-05 9 views
11

मैं पूरी तरह से इसकी कल्पना कर रहा हूं, लेकिन मैंने शपथ ली होगी कि रिचटेक्स्टबॉक्स में केवल व्यक्तिगत रन (या पैराग्राफ) तत्वों को पढ़ने के लिए एक तरीका था। मैं भी शपथ ली हो सकता था मैं इस बाहर अपने आप को कुछ सप्ताह पहले करने के लिए एक विधि की कोशिश की और परिणामों से संतुष्ट था - मैं थोड़ा याद यह कुछ इस तरह देखा:एक WPF RichTextBox में केवल पढ़ने के तत्वों को पढ़ें?

<RichTextBox x:Name="richTextBox" 
      AcceptsTab="True" 
      AcceptsReturn="True" 
      FontFamily="Courier New" 
      FontSize="14"> 
    <FlowDocument> 
     <Paragraph> 
      <Run IsReadOnly="True">I wish this was read-only!</Run> 
     </Paragraph> 
    </FlowDocument> 
</RichTextBox> 

अब, कुछ ही हफ्ते बाद, मैं जाना रन तत्वों को केवल एक RichTextBox में पढ़ने के लिए केवल यह खोजने के लिए कि यह संभव नहीं लगता है।

This post on the MSDN forums इसकी पुष्टि करने के लिए लगता है।

क्या मैंने पूरी तरह से इसकी कल्पना की? या क्या मैं ऐसा करना चाहता हूं जो मैं करना चाहता हूं?

उत्तर

7

ठीक है, मैं एक ऐसे समाधान के साथ आया हूं जो मेरे मामले के लिए काम करता है - लेकिन ऐसा कुछ नहीं चाहता जो इस तरह कुछ चाहें। यह गन्दा है, लेकिन यह नौकरी करता है।

मैं कुछ दिनों के लिए अपना उत्तर स्वीकार नहीं कर रहा हूं, बस अगर किसी और के पास इसे पूरा करने का बेहतर तरीका है।

ये हम चले, पहले, XAML:

<Window x:Class="WpfApplication1.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Window1" 
     Height="500" 
     Width="600"> 
    <DockPanel LastChildFill="True"> 
     <RichTextBox x:Name="rtb" 
        FontFamily="Courier New" 
        FontSize="14" 
        PreviewKeyDown="rtb_PreviewKeyDown"> 
      <FlowDocument> 
       <Paragraph> 
        <InlineUIContainer Unloaded="InlineUIContainer_Unloaded"> 
         <TextBlock FontFamily="Courier New" FontSize="14">This line of text is not editable.</TextBlock> 
        </InlineUIContainer> 
        <Run Foreground="Blue">But this is editable.</Run> 
       </Paragraph> 
      </FlowDocument> 
     </RichTextBox> 
    </DockPanel> 
</Window> 

और पीछे कोड:

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 

namespace WpfApplication1 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
     } 

     private void InlineUIContainer_Unloaded(object sender, RoutedEventArgs e) 
     { 
      (sender as InlineUIContainer).Unloaded -= new RoutedEventHandler(InlineUIContainer_Unloaded); 

      TextBlock tb = new TextBlock(); 
      tb.FontFamily = new FontFamily("Courier New"); 
      tb.FontSize = 14; 
      tb.Text = "This line of text is not editable."; 

      TextPointer tp = rtb.CaretPosition.GetInsertionPosition(LogicalDirection.Forward); 
      InlineUIContainer iuic = new InlineUIContainer(tb, tp); 
      iuic.Unloaded += new RoutedEventHandler(InlineUIContainer_Unloaded); 
     } 

     private void rtb_PreviewKeyDown(object sender, KeyEventArgs e) 
     { 
      if (e.Key == Key.Enter) 
      { 
       var newPointer = rtb.Selection.Start.InsertLineBreak(); 
       rtb.Selection.Select(newPointer, newPointer); 

       e.Handled = true; 
      } 
     } 
    } 
} 

मेरे समाधान तथ्य यह है कि जब एक InlineUIContainer यूआई से निकाल दिया जाता है, यह Unloaded() है पर निर्भर करता है विधि कहा जाता है। उस बिंदु पर, मैं वर्तमान कैरेट स्थिति पर हटाए गए InlineUIContainer को फिर से जोड़ता हूं।

किसी भी हैक के साथ, नुकसान का एक गुच्छा है।

  • पाठ मैं केवल पढ़ने के लिए किए जाने की एक InlineUIContainer में लिपटे होने की जरूरत हैं: नुकसान मैं खोजने हूँ अनुसरण कर रहे हैं। यह इस समाधान के लिए थोड़ा सीमित है।
  • मुझे 'एंटर' कुंजी कैप्चर करना है और मैन्युअल रूप से लाइन ब्रेक डालना है, अन्यथा, InlineUIContainer.Unloaded() प्रत्येक बार एंटर कुंजी दबाए जाने पर फायरिंग रखता है। मजेदार नहीं है, लेकिन यह मेरे मामले के लिए काम करता है।

यह एक अच्छा समाधान नहीं है, लेकिन मुझे लगता है कि यह मेरे लिए काम करेगा। जैसे मैंने कहा, मैं इसे अभी तक अपने प्रश्न के उत्तर के रूप में चिह्नित नहीं कर रहा हूं - उम्मीद है कि किसी और के पास ऐसा करने का बेहतर तरीका होगा।

+2

बहुत दिलचस्प यह मदद मिलेगी मुझे जोड़ें "विजेट्स" अगर आप टेक्स्ट एडिटर में होंगे। मैं विकी संपादक की तरह एक बहुत अच्छी खिड़कियां बना रहा हूँ। तो छवियों, श्रेणियों और खोजशब्दों को जोड़ने के लिए मैं छोटी वस्तुओं का उपयोग कर रहा हूं जो समृद्ध टेक्स्ट ऑब्जेक्ट को सजाने के लिए तैयार हैं। मेरी इच्छा है कि संपादक दृश्य स्टूडियो संपादक की तरह थोड़ा और अधिक था। इस तरह से मैं "सजावट" जोड़ सकता हूं लेकिन ... यह निश्चित रूप से मेरी मदद करता है! धन्यवाद। – JustinKaz

+0

खुशी है कि यह मदद कर सकता है - चेतावनी दी जानी चाहिए, हालांकि - मुझे लगता है कि बैकस्पेस कुंजी के साथ केवल-पढ़ने वाले पाठ को हटाना संभव है।मुझे इस समय के बाद निश्चित नहीं है, लेकिन यह सुनिश्चित करने के लिए कि विजेट केवल पढ़ने के लिए ही पूरी तरह से परीक्षण करेंगे। –

1

यह दो घटना से निपटने के द्वारा प्राप्त किया जा सकता है: 1) OnMouseDown 2)

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Controls; 
using System.Windows; 
using System.Windows.Input; 

namespace WpfApplication2 
{ 
public class MultiPartTextBox : TextBox 
{ 
    private string _prefix; 
    private string _content; 

    public string Prefix 
    { 
     get { return _prefix; } 
     set { _prefix = value; 
     Text = _prefix; 
     } 
    } 

    public string Content 
    { 
     get { return _content; } 
     set { 
      _content = value; 
      Text = _prefix + _content; 
     } 
    } 

    public MultiPartTextBox() { _prefix = string.Empty; } 

    protected override void OnMouseDown(MouseButtonEventArgs e) 
    { 

     base.OnMouseDown(e); 
     this.SelectionStart = _prefix.Length; 
     this.SelectionLength = 0; 
    } 

    //tab In 
    protected override void OnGotFocus(RoutedEventArgs e) 
    { 
     this.SelectionStart = _prefix.Length; 
     this.SelectionLength = 0; 
     base.OnGotFocus(e); 
    } 

    protected override void OnPreviewKeyDown(KeyEventArgs e) 
    { 
     if (e.Key == Key.Back 
      || e.Key == Key.Delete 
      || e.Key==Key.Left) 
     { 
      if (CaretIndex <= _prefix.Length) 
      { 
       e.Handled = true; 
       return; 
      } 
     } 
     base.OnPreviewKeyDown(e); 
    } 
    } 
    } 
Xaml में

OnPreviewKeyDown हम निम्नलिखित तरीके से इसे संभाल करने के लिए है:

xmlns:uc="clr-namespace:WpfApplication2" 

     <uc:MultiPartTextBox Height="30" HorizontalAlignment="Left" 
      Margin="80,94,0,0" x:Name="multiPartTxt1" VerticalAlignment="Top" 
      Width="224" Prefix="NON-EDITABLE" CaretIndex="4" >    
     </uc:MultiPartTextBox> 
+0

आप उंगली के स्पर्श के बारे में भूल गए हैं। – McKay

संबंधित मुद्दे