2012-10-31 16 views
4

我試圖讓一個RichTextBox的內容高度,如果超過500像素,將其分割成具有500像素的最大高度多RichTextBoxes。拆分過高大WPF的RichTextBox成多個控制

任何人都知道如何做到這一點?謝謝。

編輯:

通過「拆分」我的意思是把超過在另一RichTextBox的高度限制的內容,該解決方案不能只是改變因項目特殊性當前的RichTextBox的appearence。

+1

拆分意味着特定的佈局配置。你打算讓他們在一個特定的面板/物品控制? – Sisyphe

+2

僅用於顯示還是需要分割後端數據?您可以通過相同的數據綁定到多個文本框,並覆蓋滾動位置 –

+0

@BobVale您的解決方案聽起來不錯,有可能實現這一目標,唯一的一點是,用戶將能夠編輯RichTextBox的內容,因此,如果用戶滾動內容他們會看到隱藏的內容,有什麼方法可以更改滾動並刪除所有不可見的文本? –

回答

1

要獲得超過在另一RichTextBox的高度限制的內容,我會用下面的辦法:

private TextRange GetTopRange() 
    { 
     var result = textBox.GetPositionFromPoint(new Point(0, 0), true); 
     if (result == null) 
      return null; 
     result = result.GetInsertionPosition(LogicalDirection.Forward); 
     return new TextRange(result.DocumentStart, result); 
    } 

    private TextRange GetBottomRange() 
    { 
     var result = textBox.GetPositionFromPoint(new Point(textBox.ActualWidth, textBox.ActualHeight), true); 
     if (result == null) 
      return null; 
     result = result.GetInsertionPosition(LogicalDirection.Backward); 
     return new TextRange(result, result.DocumentEnd); 
    } 

具有文本範圍內,你可以將其複製到另一個RichTextBox的一個新的FlowDocument,截斷它們(range.Text = string.Empty)等

+0

這聽起來不錯,我來試試這個方法。後來我告訴你它是否有效。謝謝 –

1

您是否嘗試過在RichTextBox.ContentsResized事件中使用此代碼。

Private Sub rtb_ContentsResized(ByVal sender As Object, ByVal e As System.Windows.Forms.ContentsResizedEventArgs) Handles txtQuestion.ContentsResized 
    Dim h = e.NewRectangle.Height, w = e.NewRectangle.Width 
    h = Math.Max(h, sender.Font.Height) 
    h = Math.Min(h, Me.ClientSize.Height - 10 - sender.Top) 
    h += sender.Height - sender.ClientSize.Height + 1 
    sender.Height = h 

末次

如果有這方面的任何替代的C#代碼,我不知道。

還額外信息 - RichTextBox控件使用GDI繪製,而 'Graphics.MeasureString' measuers使用GDI +的字符串。因此 'MeasureString'不會返回字符串的確切大小。我擔心你會 必須挖掘到GDI32-API才能得到確切的結果。如果您有興趣使用Win32 GDI API調用,look here

+0

我不能強行改變我的RichTextBox的高度,因爲每個RichTextBox中的所有內容應符合500PX的最大高度,所以,如果我改變heigth RichTextBox中可以超過最大高度。這是一個WPF應用程序,所以代碼不能基於Windows窗體組件,謝謝。 –

+0

WPF RichTextBox不提供調整文本寬度的功能。據我所知,RichTextBox在其可視化樹中使用FlowDocumentView來呈現Flowdocument。它將佔用可用空間來渲染其內容,因此它不會將其大小調整爲內容。由於這是一個內部類,因此我們似乎無法重寫佈局過程以使RichTextBox將其大小調整爲文本。嘗試遞歸地循環訪問RichTextBox中的flowdocument,或者使用具有水平和垂直對齊屬性的網格來包裝RTB。 –

1

我覺得我得到了你answer..Thanks谷歌和計算器。

一個WPF的FlowDocument只能屬於一個RichTextBox的。但是,如果您使用的單個文檔可以在UI中的不同位置進行操作,那麼不會發生有兩個RichTextBoxes同時顯示單個文檔(並且不能,因爲WPF會投訴)。但是你使用單個文件還是多個文件?如果是單身,請閱讀其餘部分,如果不是,請繼續前進。

使用MemoryStream和XamlReader/Writer將不會在這裏工作,因爲我們希望保留單個文檔並反映所使用的更改,因此每次都複製它。 從計算器的成員賈裏德複製,

WPF控件可以「unparented」和隨意「重設父」,所以才使整個精靈共享上下文提供的RichTextBox的實例,並確保你unparent /重新設置父級隨着您逐頁移動。這也有利於在嚮導的頁面中保存任何樣式或對編輯器狀態的更改(這可能是可取的)。

如果不能跨頁面共享RichTextBox實例,我認爲有一種方法可以從原始RichTextBox中分離文檔。看來,爲了從RichTextBox1中取消關聯文檔,您必須爲RichTextBox1提供一個新文檔。您不能將RichTextBox1.Document設置爲null,但您可以將RichTextBox1.Document設置爲新的FlowDocument(),我相信這會起作用。

從上文的FlowDocument不能由幾個RichTextBox的共享直接控制.. 因此,正如我上面發表評論,請使用網格

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition /> 
     <ColumnDefinition /> 
    </Grid.ColumnDefinitions> 

    <Grid.RowDefinitions> 
     <RowDefinition /> 
     <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 

來包裝RTB和使用後面的代碼

FlowDocument doc = RTB1.Document; 
    RTB1.Document = new FlowDocument(); 
    RTB2.Document = doc; 

我不知道這是否會分裂的控制,但我們可以看到該文件(單)在另一個RTB。

+0

我正在使用多個文檔,但感謝您的幫助。 –

3

我打了一下這個分裂RichTextBox的問題,這是不容易的^^ 我的想法是這樣的:

  • 創建SplitRichTextBox CustomControl將繼承RichTextBox的(主要是爲了讓所有的depency屬性)
  • 添加MaxContentHeight雙重依賴屬性來管理最大尺寸(在你的案件500像素)
  • 添加所剩下的人的IList <的RichTextBox>依賴屬性,這將是你目前剩餘一旦SplitRichTextBox它被拆分。
  • 自定義您的SplitRichTextBox的控件模板來顯示,將滿足您的佈局需要一個面板SplitRichTextBox內容和餘數。
  • 覆蓋OnTextChanged方法對你SplitRichTextBox。

在此方法中檢索底層richTextBox flowDocument並檢索分頁符。設置MaxPageHeight並計算文檔頁面。

var flowDocument = this.Document; 
flowDocument.MaxPageHeight = this.MaxContentHeight; 
DocumentPaginator paginator = ((IDocumentPaginatorSource)flowDocument).DocumentPaginator; 
paginator.ComputePageCount(); 

由於paginator上的GetPage(int i)方法,您現在可以檢索每個頁面的內容。第一頁是你想要的第一個RichTextBox。保留頁面將用於實例化Remains依賴項屬性。

問題是,頁面不是直接RTF或FlowDocument的。您需要以某種方式從paginator/page中提取數據以獲取如何分割文檔。這是我停下來的地方,也可能不是這條路,但我認爲這值得嘗試。

祝你好運!

+0

這聽起來不錯,我會首先嚐試@ Serge-Belov的方法,因爲它不需要改變類的層次結構,如果它不起作用,我會嘗試你的。謝謝我非常感謝你的幫助。 –

+0

如果有人在這個答案絆倒,這裏是從每個DocumentPage檢索數據的一種方法:[是否有可能在WPF中獲取每個DocumentPage的內容按頁碼?](http://stackoverflow.com/questions/25806961/是-IT-可能功能於WPF對獲得化內容的,每個-documentpage按頁號) – Absolom

-1
public void CreateNewRtb(object sender, RoutedEventArgs routedEventArgs) 
{ 
    var res = (ResourceDictionary)Application.LoadComponent(new Uri("/Design/Style/TextAreaStyle.xaml", UriKind.Relative)); 
    var mcRtb = new RichTextBox {Style = (Style) res["TextBoxStyle"], Name = "Folha" + J}; 
    RegisterName("Folha" + J, mcRtb); 
    mcRtb.TextChanged += McRtbContentControl; 
    var gcrd = new RowDefinition(); 
    var gcrdspace = new RowDefinition(); 
    gcrd.Height = new GridLength(980); 
    GridControl.RowDefinitions.Add(gcrd); 
    Grid.SetColumn(mcRtb, 1); 
    Grid.SetRow(mcRtb, 1 + I); 
    GridControl.Children.Add(mcRtb); 
    I += 2; 
    J++; 
    gcrdspace.Height = new GridLength(30); 
    GridControl.RowDefinitions.Add(gcrdspace); 
    mcRtb.Focus(); 
} 

這是控制月牙網格大小一個簡單的方法,並且還以隨意 創建RTB:d