I am new to Windows Presentation Framework, don't know most of it. Please answer with example code, how to get only all selected TableCell from a Table in WPF RichTextBox? I tried to get all the selected TableCell items by using TextSelection.Start and TextSelection.End but this gives wrong results. This yields selected cells but also one or more unselected unwanted cells. It seems a bug in WPF Richtextbox, or my code implementation is wrong and some other code is to be implemented. No idea what the code is to get only the selected TableCell items without any additional unselected TableCell. Kindly also inform example code to get all selected TableRow of a Table.
public List<TableCell> GetSelectedCells(System.Windows.Controls.RichTextBox rtb, TextSelection selection)
{
List<TableCell> cells = new List<TableCell>();
var curCaret = CaretPosition;
Table table = rtb.Document.Blocks.OfType<Table>().Where(x => x.ContentStart.CompareTo(curCaret) == -1 && x.ContentEnd.CompareTo(curCaret) == 1).FirstOrDefault();
if (table == null) return cells;
if (table.RowGroups.Count == 0) return cells;
foreach (TableRowGroup rowGroup in table.RowGroups)
{
foreach (TableRow row in rowGroup.Rows)
{
// option 1, this also yields additional unselected cells
List<TableCell> selcells = row.Cells.Where(w => selection.Contains(w.ContentStart) && selection.Contains(w.ContentEnd)).ToList();
// option 2, this also yields additional unselected cells.
foreach (TableCell cell in selcells)
{
if (selection.Contains(cell.ElementStart) && selection.Contains(cell.ElementEnd))
cells.Add(cell);
}
}
}
return cells;
}
I tried 2 different code which is described as "option 1" or "option 2" or both options. i cannot get perfect and exact results but only wrong results with additional unselected unwanted TableCell. I want to get all the selected TableCell items only, but not any other TableCell.
FlowDocumentis a component based document model.This means, it is generally a bad idea to search the document text based when you are interested in elements of the content model, for example a
TableCell.The general approach is to use a
TextPointercontext based search as this is the only convenient way to get access to the content elements.The idea is to get the
TextPointerthat points to the start of an element. Then check if this element is the element of interest. If it's not, advance theTextPointerto the next position by using theTextPointerAPI.To support your open source project I will post a modified example of some library code. It's reduced to satisfy the minimum requirement without sacrificing the generic nature. I have also annotated it with some comments that help to understand the implementation. For convenience, I have converted the code into an extension method.
The following algorithm is a generic implementation that allows to find any kind of
ContentElementorUIElement.As a general note, the implementation of
TryGetNextElementshows the common algorithm to step through aFlowDocumentcontext based to inspect its elements:TextRangeHelper.cs
Usage Example
After selecting some text in the
Tablewithin aFlowDocument, aButton.Clickhandler will actually execute the extraction of the selectedTableCellitems and their cell values:MainWindow.xaml.cs