2011-09-16 33 views
3

這裏是一個非常簡單的代碼示例:當RichTextBox只是加載/空時,WPF EditingCommands不工作?

<DockPanel> 
    <ToolBar DockPanel.Dock="Top" IsTabStop="False"> 
     <ToggleButton MinWidth="40" Command="EditingCommands.ToggleBold" CommandTarget="{Binding ElementName=XAMLRichBox}" TextBlock.FontWeight="Bold" IsTabStop="False">B</ToggleButton> 
    </ToolBar> 
    <RichTextBox x:Name="XAMLRichBox" SpellCheck.IsEnabled="True" MinHeight="100"/> 
</DockPanel> 

當我運行它,輸入的東西到RichTextBox後,我可以使用ToggleButton得到BOLD效果,一切都很好。

但如果我鍵入任何東西到RichTextBox(無論RichTextBox獲得焦點與否),雖然ToggleButton成爲Checked之前單擊ToggleButton,我RichTextBox仍然使用正常方式(不BOLD),直到我再次點擊ToggleButton。 這是一個錯誤?我該如何解決?謝謝!

+0

我知道這是舊的,但是當你還在所以在這時間,你介意告訴我們,如果你找到了解決辦法嗎?它仍然沒有答案,不僅在這裏... –

+0

@Sinity,尚未找到解決方案,但您的答案看起來像一個快速修復。謝謝! – Bolu

回答

3

Mainwindow.xaml

<DockPanel> 
    <ToolBar 
     DockPanel.Dock="Top" 
     IsTabStop="False"> 
     <ToggleButton 
      x:Name="boldButton" 
      Command="EditingCommands.ToggleBold" 
      CommandTarget="{Binding ElementName=XAMLRichBox}" 
      TextBlock.FontWeight="Bold" 
      ToolTip="Bold"> 
      B 
     </ToggleButton> 
    </ToolBar> 
    <RichTextBox 
     x:Name="XAMLRichBox" 
     SpellCheck.IsEnabled="True" 
     SelectionChanged="SynchronizeWith" 
     MinHeight="100" /> 
</DockPanel>  

Mainwindow.xaml.cs

private void SynchronizeWith(object sender, RoutedEventArgs e) 
    { 
     object currentValue = XAMLRichBox.Selection.GetPropertyValue(TextElement.FontWeightProperty); 
     boldButton.IsChecked = (currentValue == DependencyProperty.UnsetValue) ? false : currentValue != null && currentValue.Equals(FontWeights.Bold); 

    } 
+1

謝謝,這將同步togglebutton的狀態與'RichTextBox'。但是,'EditingCommands.ToggleBold'不會工作util用戶輸入的東西。 – Bolu

3

我發現了一個半的​​解決方案,我想我也有同感,因爲這個問題是不是在網上和我上的任何地方回答認爲很多人都有問題。

我在構造函數中設置了變量NewInput。當richTextBox中的第一個輸入將被觸發時,我會將每個需要的格式應用到控件中。

private bool NewInput; 
private void richTxt_PreviewTextInput(object sender, TextCompositionEventArgs e) 
{ 
    if (NewInput) 
    { 
     richTxt.BeginChange(); 
     TextPointer startPosition = richTxt.Selection.Start; 
     Run r = new Run(e.Text, startPosition); 
     if (IsSelectionBold) 
     { 
      r.FontWeight = FontWeights.Bold; 
     } 
     if (IsSelectionItalic) 
     { 
      r.FontStyle = FontStyles.Italic; 
     } 
     if (IsSelectionUnderlined) 
     { 
      r.TextDecorations = TextDecorations.Underline; 
     } 
     r.FontSize = double.Parse(SelectedFontHeight); 
     r.FontFamily = new FontFamily(SelectedFont); 

     richTxt.EndChange(); 


     NewInput = false; 
     e.Handled = true; 
     richTxt.CaretPosition = richTxt.CaretPosition.GetPositionAtOffset(1); 
    } 
} 

然後,我在正確的地方更換了卡雷。像這樣,即使RichTextBox中沒有任何內容,也可以保持格式化。

我相信它有一天會幫助別人。

0

@Sinity已經接近了,但只有在文本塊位於文本塊內時,該解決方案纔會生效。

運行結束時有兩個位置:Run.ContentEndRun.ElementEnd。看起來ContentEnd「正好在運行之外」(所以輸入的任何新文本都不會影響運行的樣式),但ElementEnd僅在運行結束時顯示,並且輸入的文本被添加到運行中。

這裏是一個修改的方案(適用未決的粗體字爲例),似乎在所有情況下工作:

private bool IsBoldStylePending { get; set; } 
private void RichTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) 
{ 
    if (!IsBoldStylePending) 
     return; 

    rtb.BeginChange(); 
    Run run = new Run(e.Text, rtb.CaretPosition); // Add the next character with style 
    run.FontWeight = FontWeights.Bold; 
    rtb.EndChange(); 

    rtb.CaretPosition = run.ElementEnd;   // Keep caret just within the run 

    IsBoldStylePending = false; 
    e.Handled = true; 
} 
相關問題