c# FlowDocument изменить часть текста
В FlowDocumentPageViewer загружается fb2 файл, функция создает дерево узлов которое отправляется в TreeView, при выборе узла из него в окно загружается текст главы. В тексте бывают сноски вида <a l:href="#note1" type="note">[1]</a>, и они выделяются цветом и добавляется Tooltip с текстом сноски(фрагмент кода выделен). Проблема в том что не все ссылки выделяются правильно, неверно определяется позиция в тексте, и сноска может быть до или после нужной позиции и затирать часть текста. Как можно решить проблему?
Пример: был текст
<p>Урсус и Гомо были связаны узами тесной дружбы. Урсус<a type="note" l:href="#n_1">[1]</a> был человек, Гомо<a type="note" l:href="#n_2">[2]</a> – волк.
Получился:
Урсус и Гомо были связаны узами тесной дружбы. Урсус[1] был человек, [2]о[2] – волк.
public class Node
{
public string Title { get; set; }
public List<Node> Nodes { get; set; }
public FlowDocument Flowdoc { get; set; }
}
private List<Node> getSections(XElement xelem)
{
List<Node> nodes = new List<Node>();
foreach (XElement section in xelem.Elements(fb + "section"))
{
string sectionTitle = "";
iter++;
if (section.Elements(fb + "title").ToArray().Length > 0)
{
foreach (XElement titleParagraphs in section.Element(fb + "title").Elements(fb + "p"))
{
sectionTitle += titleParagraphs.Value + " ";
}
}
else sectionTitle = "Без названия";
string plink = "link_" + iter;
FlowDocument sectionFlowdoc = new FlowDocument();
Paragraph titleParag = new Paragraph(new Run(sectionTitle))
{
Name = plink,
FontWeight = FontWeights.Bold
};
sectionFlowdoc.Blocks.Add(titleParag);
foreach (XElement sectionElem in section.Elements())
{
if (sectionElem.Name == fb + "p")
{
Paragraph pr = new Paragraph();
pr.Inlines.Add(new Run(sectionElem.Value));
pr.Name = "link_" + iter;
string a_href = "", a_val = "";
if (sectionElem.Elements(fb + "a").ToArray().Length > 0)
{// ПОИСК ЭЛЕМЕНТОВ <A>
foreach (XElement a in sectionElem.Elements(fb + "a"))
{
a_href = a.Attribute(link + "href").Value.Substring(1);
a_val = a.Value;
TextRange trange = new TextRange(pr.ContentStart, pr.ContentEnd);
int pos = trange.Text.IndexOf(a_val, StringComparison.OrdinalIgnoreCase);
if (pos >= 0)
{
TextPointer start = trange.Start.GetPositionAtOffset(pos);
TextPointer end = trange.Start.GetPositionAtOffset(pos + a_val.Length);
TextRange textR = new TextRange(start, end);
textR.Text = "";
string note_val = xdoc.Descendants(fb + "body")
.Where(b => (string)b.Attribute("name") == "notes")
.First()
.Descendants(fb + "section")
.Where(s => (string)s.Attribute("id") == a_href)
.First()
.Elements(fb + "p").First().Value;
ToolTip tt = new ToolTip();
tt.Background = Brushes.LightYellow;
tt.Content = new Label() { Content = note_val };
Run newRun = new Run(a_val, start);
newRun.Foreground = Brushes.Red;
newRun.Cursor = Cursors.Hand;
newRun.ToolTip = tt;
}
}
}
sectionFlowdoc.Blocks.Add(pr);
}
}
Node n = new Node()
{
Title = sectionTitle,
Flowdoc = sectionFlowdoc,
};
if (section.HasElements)
{
n.Nodes = getSections(section);
}
nodes.Add(n);
}
return nodes;
}
Выбор главы
BookContentsTree_SelectedItemChanged
Node nd = (Node)bookContentsTree.SelectedItem;
fdviewer.Document = nd.Flowdoc;