- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
您好,我目前正在处理涉及使用 RichTextBox 的 WPF 项目(使用/C#)。我目前已经完成了大部分工作,但需要帮助通过鼠标选择获得多个 block ,例如设置 TextAlignment 或 Margin。供您引用,以下将通过为 RichTextBox 插入符号设置 TextPointer 来选择 one block ,然后遍历 Document.Blocks 以获得一个个人 block 。但我想要一种能让我获得的不仅仅是一个区 block 的方法。有人可以更深入地了解如何选择多个 block (每个 block 在不同的行上)吗?
// XAML
<RichTextBox Name="rtb" HorizontalAlignment="Left">
<FlowDocument>
<Paragraph TextAlignment="Left" Margin="0.0">
<Run Text="Hello"/>
</Paragraph>
<Paragraph TextAlignment="Right" Margin="0.0">
<Run Text="World"/>
</Paragraph>
<Paragraph TextAlignment="Left" Margin="1.0">
<Run Text="Hello"/>
</Paragraph>
<Paragraph TextAlignment="Right" Margin="1.0">
<Run Text="World"/>
</Paragraph>
</FlowDocument>
</RichTextBox>
// Code Behind
var curCaret = rtb.CaretPosition;
Block curBlock = rtb.Document.Blocks.Where(x => x.ContentStart.CompareTo(curCaret) == -1 && x.ContentEnd.CompareTo(curCaret) == 1).FirstOrDefault();
最佳答案
如果你只想找到顶级Blocks
与当前 selection range 重叠,你可以这样做:
public static class FlowDocumentHelper
{
public static bool Overlaps(this TextElement element, TextPointer start, TextPointer end)
{
return element.ContentEnd.CompareTo(start) > 0 && element.ContentStart.CompareTo(end) < 0;
}
}
然后
var blocks = richTextBox.Document.Blocks.Where(block => block.Overlaps(richTextBox.Selection.Start, richTextBox.Selection.End));
但是,如果您正在寻找 paragraphs与当前选择范围重叠这将不起作用,因为它们可能深埋在文本元素层次结构中,例如在 figure 中在 list 里面在 table 里面在 section 里面.要真正发现与当前选择范围重叠的段落,您必须递归遍历 block 的层次结构,而 WPF 没有提供直接的方法来执行此操作(尽管它们内部肯定有此信息!)。
因此,可以为所有可能的 TextElement
手工制作递归迭代器。可能包含 child 的类,或遍历所有 TextPointer
文档中的对象并使用它们来发现层次结构。下面使用后一种策略:
public static class FlowDocumentHelper
{
public static IEnumerable<TTextElement> WalkTextRange<TTextElement>(this FlowDocument doc, TextPointer start, TextPointer end) where TTextElement : TextElement
{
var lastVisited = new Dictionary<int, TTextElement>();
foreach (var stack in doc.WalkTextHierarchy())
{
var element = stack.Peek() as TTextElement;
if (element != null)
{
TTextElement previous;
if (!lastVisited.TryGetValue(stack.Count - 1, out previous) || previous != element)
{
if (element.Overlaps(start, end))
yield return element;
lastVisited[stack.Count - 1] = element;
}
}
}
}
public static bool Overlaps(this TextElement element, TextPointer start, TextPointer end)
{
return element.ContentEnd.CompareTo(start) > 0 && element.ContentStart.CompareTo(end) < 0;
}
public static IEnumerable<Stack<DependencyObject>> WalkTextHierarchy(this FlowDocument doc)
{
if (doc == null)
throw new ArgumentNullException();
var stack = new Stack<DependencyObject>();
// Keep a TextPointer for FlowDocument.ContentEnd handy, so we know when we're done.
TextPointer docEnd = doc.ContentEnd;
// Keep going until the TextPointer is equal to or greater than ContentEnd.
for (var iterator = doc.ContentStart;
(iterator != null) && (iterator.CompareTo(docEnd) < 0);
iterator = iterator.GetNextContextPosition(LogicalDirection.Forward))
{
var parent = iterator.Parent;
// Identify the type of content immediately adjacent to the text pointer.
TextPointerContext context = iterator.GetPointerContext(LogicalDirection.Forward);
switch (context)
{
case TextPointerContext.ElementStart:
case TextPointerContext.EmbeddedElement:
case TextPointerContext.Text:
PushElement(stack, parent);
yield return stack;
break;
case TextPointerContext.ElementEnd:
break;
default:
throw new System.Exception("Unhandled TextPointerContext " + context.ToString());
}
switch (context)
{
case TextPointerContext.ElementEnd:
case TextPointerContext.EmbeddedElement:
case TextPointerContext.Text:
PopToElement(stack, parent);
break;
case TextPointerContext.ElementStart:
break;
default:
throw new System.Exception("Unhandled TextPointerContext " + context.ToString());
}
}
}
static int IndexOf<T>(Stack<T> source, T value)
{
int index = 0;
var comparer = EqualityComparer<T>.Default;
foreach (T item in source)
{
if (comparer.Equals(item, value))
return index;
index++;
}
return -1;
}
static void PopToElement<T>(Stack<T> stack, T item)
{
for (int index = IndexOf(stack, item); index >= 0; index--)
stack.Pop();
}
static void PushElement<T>(Stack<T> stack, T item)
{
PopToElement(stack, item);
stack.Push(item);
}
}
然后
var paragraphs = richTextBox.Document.WalkTextRange<Paragraph>(richTextBox.Selection.Start, richTextBox.Selection.End);
(注意 - 经过适度测试的非生产代码。)
最后,如果您想让您的用户使用 Ctrl-Select 多个不相邻的文本范围,可以在 Word 中完成,如下所述:Select items that aren't next to each other ,那我觉得你运气不好。 RichTextBox 似乎不支持此用户交互。
关于c# - WPF RichTextBox - 多 block 选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25149593/
我对 RichTextBox 控件感到困惑。 我的 WinForm 有一个 RichTextBox 控件,宽度为 100px。我想动态创建一个然后引用实例。 因此,假设在我的 Form 上我有一个名为
MouseDown 事件处理程序的 KeyDown 事件处理程序中 e.Handled = true 的等价物是什么?我不希望鼠标事件对 RichTextBox 有任何影响(完全禁用鼠标与 RichT
我有一个 richtextbox,它的文本是特定表格中一些单词的串联。 (表格列是'word','translate'和'id') 我需要当用户将鼠标悬停在每个单词上时,相关的翻译会显示在单词的工具提
您好,我在将 richtextbox 中的数据显示或传输到其他 richtextbox 时遇到问题... richtextbox1.Document = richtextbox2.Document;
我正尝试在我的 Windows Phone 8 应用程序中使用 RichTextBox。用户需要能够选择文本并将其复制到剪贴板。用户不需要编辑文本,只需选择它。但是,我似乎无法在 Windows Ph
我有一个 Winforms 项目,我可以在其中将文本写入 RichTextBox,还有一些控件可以设置所写文本的字体格式。我能够将文本保存并附加到 RTF 文件,但我在保留每个 RichTextBox
假设我有以下内容:
我需要一些具有富文本编辑功能的基本 CMS 功能。在 stack overflow 上有一个常规的文本区域编辑控件,支持 Markdown 样式语法格式。那将超出我的用户范围,所以我想要一个类似丰富的
显示图像: 复制代码代码如下: Image img = Image.FromFi
我遇到过 RichTextBox 的一些奇怪行为。我希望它是readonly,但是当我使用时它不显示图像richTextBox.LoadFile(path) 方法加载.rtf 文件。当它不是reado
我需要将 ScrollBars 设置为 ForcedBoth 但我还想知道 ScrollBars 的句柄何时可见并且用户可以滚动。 两个滚动条的 bool 值都可以 这里用户不能滚动: 在这里他们可以
我正在开发根据正则表达式模式在 RichTextBox 中突出显示文本的应用程序。 它工作正常,除了性能,即使对于小文本(大约 500 个字符),它也会挂起一段时间,这对用户是可见的。 我在 Flow
我在我的 WPF richtextbox 上启用了拼写,我想在显示带有拼写建议的上下文菜单之前在当前插入符号位置获取拼写错误的单词。 最佳答案 新方式 void richTextBox1_Pr
我在 .NET Windows 窗体应用程序中使用 RichTextBox 控件。我允许用户在文本框本身内按 TAB 键。但是,当我将 .Text 值保存在文本框中时,它将显示如下: "This[]i
我在 MS Word 中创建了带有超链接的 rtf 文件并将其加载到 RichTextBox 中。 RichTextBox 中的超链接不起作用。 RichTextBox 和 MS Word 使用不同的
有没有办法改变 RichTextBox 中下划线的颜色? ? 我试过 this但它似乎不起作用。有人知道这些枚举值是从哪里来的吗?没有看到它的任何文档。 谢谢。 最佳答案 枚举值是将消息传递给控件时的
这是交易:我有一个 RichTextBox 控件,它工作正常。问题是有一个“插入当前日期时间”按钮,它将当前日期时间添加/注入(inject)到 RichTextBox 中。用户可以在插入符号指向的任
我正在编写一个小应用程序,我可以在其中加载文本文件以匹配正则表达式: 我根据匹配行的长度更改前景色文本, 问题是,如果一行是多行,那么它不会按预期工作并且只选择该行的一半,例如以“title”开头的第
我有一个 RichTextBox在我的应用程序中,它正在获取有关某些事件的新内容。 添加新内容时,我想滚动到底部,仅当 卷轴在底部 之前 . 我该怎么做呢? 更具体地说,给我带来麻烦的部分是确定滚动位
当加载 50KB 的文本文档时,WPF 的 RichTextBox 控件的性能确实很慢。滚动滞后并按 Ctrl-A 选择所有文本需要 10 多秒钟。 (这在记事本上是瞬时的)。 我没有做任何花哨的位图
我是一名优秀的程序员,十分优秀!