如何在RichEditBox中将文档与文档对齐?

时间:2014-02-03 16:07:07

标签: c# xaml position height

这是一个抽象的问题,但我无法想到其他任何问题。

我有一个带有RichText编辑器的Windows应用商店应用(使用RichEditBox控件)

这是一个极简主义的写作应用程序,我想添加一个功能,允许用户在文档中添加边距注释。用户可以在文档中的任何位置添加边距注释,然后将其保存到单独的文件中。当他们重新打开文档时,他们应该能够向上和向下滚动并在正确的位置查看边距注释。

那我该怎么做?我一直绞尽脑汁试图找出最好的方法来做到这一点。 RTF /文本文件不包含行号。我能想到的最安全的事情是计算项目的单词数量,因为即使编辑器改变宽度或字体大小,这也可以让我获得粗略的位置。但有两件事让我感到难过

假设我写了一个1000字的文件。我在400字的位置添加了一个注释。

1)如何将“400个字”映射到我的“边缘注释”网格中的垂直位置?我最好的想法:我创建了一个相同尺寸的不可见阴影RichEditBox,但高度可变。我把前400个单词放入其中,然后测量这个框的高度。我将此高度应用于相关注释(可能作为边距偏移)。我看到的这个问题是我可以想象我添加的笔记越来越慢。

2)我如何编辑?假设我回去并在我的笔记前添加200个单词,我的应用程序如何知道某个点之前添加了多少个单词?并且不必用每次击键重新运行上面的代码,只是为了确保笔记的位置是正确的?

注意mods:如果这在另一个堆栈中更合适,请随意移动它。此外,目前还没有RichEditBox标签,因此如果代表高于1500的人想要创建它,那将非常感激。

1 个答案:

答案 0 :(得分:0)

我的解决方案

最初,当我同步两个ScrollViewers(一个用于编辑器,一个用于保证金清单),调整高度等位置时,事情变得非常复杂。最终我意识到我可以把我的保证金说明相同 ScrollViewer中的列表和编辑器,而不必同步任何内容。

这是我的XAML。我删除了任何不相关的内容。

<ScrollViewer x:Name="EditorScroller" 
VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="150" />
        </Grid.ColumnDefinitions>
        <Grid x:Name="MarginNotes" Grid.Column="0" HorizontalAlignment="Right"   
             Margin="0,0,20,0"></Grid>
        <StackPanel Grid.Column="1">
            <RichEditBox x:Name="MarginHelper" Opacity="0"
                 FontSize="{Binding FontSize}"></RichEditBox>        
            <!-- in a StackPanel so that the height is not set
                 note MarginHelper must have the exact 
                 same Width and FontSize as the editor,                      
                 even though MarginHelper is not visible  -->
        </StackPanel>            
        <RichEditBox x:Name="editor" FontSize="{Binding FontSize}" 
            ScrollViewer.VerticalScrollBarVisibility="Hidden"
            Grid.Column="1" Height="Auto" BorderThickness="0" />
    </Grid>
</ScrollViewer>

请注意,MarginHelper位于StackPanel内。这意味着它不会伸展以填充Grid,并且可用于确定内容的高度

当用户按下CTRL + M时,会出现一个对话框,允许他们输入注释。然后,下面的代码附上说明

private async Task AddMarginNote(string noteText)
{                    
    // get current cursor position
    int sPos = editor.Document.Selection.StartPosition;

    // select everything from the start of the document to the current position
    editor.Document.Selection.StartPosition = 0;
    editor.Document.Selection.EndPosition = sPos;

    // get selected text
    string text = "";
    editor.Document.Selection.GetText(TextGetOptions.None, out text);

    // set MarginHelper text to selected text
    MarginHelper.Document.SetText(TextSetOptions.None, text);

    // reset the editor selection 
    editor.Document.Selection.StartPosition = sPos;

    // measure height of MarginHelper 
    // (less 25 pixels, I'm not sure where this extra height is 
    // creeping in but its the only way to make this accurate)
    double mHeight = MarginHelper.ActualHeight - 25;

    // add a note to MarginNotes
    TextBlock note = new TextBlock();
    note.Text = noteText;
    note.Foreground = new SolidColorBrush(Colors.White); 
    note.Margin = new Thickness { Top = mHeight }; 
    MarginNotes.Children.Add(note);        

    // save note to db
    // code here would store noteText along with text.Length for this document
}

我还没有添加代码来实际将这些笔记保存在任何地方,但我已经测试过成功加载它们,使用以下代码

private async void LoadNote(string noteText, int chars)
{
    // set selection 
    editor.Document.Selection.StartPosition = 0;
    editor.Document.Selection.EndPosition = chars;

    // get text
    string text = "";
    editor.Document.Selection.GetText(TextGetOptions.None, out text);

    // set MarginHelper text
    MarginHelper.Document.SetText(TextSetOptions.None, text);

    // measure height of MarginHelper
    double mheight = MarginHelper.ActualHeight - 25;

    // add a note to MarginNotes
    TextBlock note = new TextBlock();
    note.Text = noteText;
    note.Foreground = new SolidColorBrush(Colors.White);
    note.Margin = new Thickness { Top = mheight };
    MarginNotes.Children.Add(note);
}

我仍然不确定这会如何扩展,但到目前为止它似乎对中小型文档表现得相当不错。

另外,在编辑文本时,我仍然没有弄清楚如何完全抵消保存的笔记,但是当我弄明白时,我会在这里发布结果

这对我的应用来说非常具体,但是稍后可能会对其他人派上用场,所以我发布了它。