gem56
asked on
Get selected table cells in WPF RichTextBox
hi guys,
i have a table in a wpf rtb control, im trying to build a solution for merging table cells. at the moment my algorithm can determine the correct row and column spans, however im getting stuck when it comes time to delete the required cells.
initially my code worked flawlessly across column merging, however when row merging came into the picture i cant seem to find my way out. the problem was dealing with varying row spans and deleting the right cells under the right conditions, however i find that there seems to be multiple variations to have to deal with with this method. i figured the easier solution would be to collect all the cells within my RTB.Selection and and simply .Parent, .IndexOf, .Remove, etc. now my last problem is my weakness with TextPointers and trying to wrap my head around the new WPF RTB control...hence, does anyone have a solution for being able to find the TableCells within my Selection() ?
cheers
i have a table in a wpf rtb control, im trying to build a solution for merging table cells. at the moment my algorithm can determine the correct row and column spans, however im getting stuck when it comes time to delete the required cells.
initially my code worked flawlessly across column merging, however when row merging came into the picture i cant seem to find my way out. the problem was dealing with varying row spans and deleting the right cells under the right conditions, however i find that there seems to be multiple variations to have to deal with with this method. i figured the easier solution would be to collect all the cells within my RTB.Selection and and simply .Parent, .IndexOf, .Remove, etc. now my last problem is my weakness with TextPointers and trying to wrap my head around the new WPF RTB control...hence, does anyone have a solution for being able to find the TableCells within my Selection() ?
cheers
I would suggest you to use the Request Attention button and ask moderators to add the "WPF and Silverlight" zone to your question.
ASKER
done, cheers mate.
How are you building the content for the RichTextBox? The usual assumption is a FlowDocument...
ASKER
Hello TheLearnedOne,
yes the content is contained within a flow document.
yes the content is contained within a flow document.
Here is a little LINQ magic, that I came up with, but I haven't had a chance to test:
public static List<Paragraph> GetSelectedParagraphs(Flow Document document, TextSelection selection)
{
return document.Blocks.OfType<Par agraph>(). Where(w => selection.Contains(w.Conte ntStart)). ToList();
}
public static List<Paragraph> GetSelectedParagraphs(Flow
{
return document.Blocks.OfType<Par
}
ASKER
hello again TheLearnedOne, thanks for the reply.
i've just converted your code to the vb equivalent, however unfortunately either the conversion isnt correct...or somethings not working in the function. basically i just keep getting an empty list returned.
any ideas?
cheers
i've just converted your code to the vb equivalent, however unfortunately either the conversion isnt correct...or somethings not working in the function. basically i just keep getting an empty list returned.
Public Function GetSelectedCells(ByVal selection As TextSelection) As List(Of TableCell)
Return flowDoc.Blocks.OfType(Of TableCell)().Where(Function(w) selection.Contains(w.ContentStart)).ToList()
End Function
any ideas?
cheers
I would suggest breaking that down, and see what is failing:
1) Dim cellList As List(Of TableCell) = flowDoc.Blocks.OfType(Of TableCell).ToList()
2) Dim selectedCellList As List(Of TableCell) = cellList.Where(Function(w) selection.Contains(w.Conte ntStart)). ToList()
1) Dim cellList As List(Of TableCell) = flowDoc.Blocks.OfType(Of TableCell).ToList()
2) Dim selectedCellList As List(Of TableCell) = cellList.Where(Function(w)
ASKER
ok so i've done a little learning and playing around with these lambda functions and OfType/Where methods. seems that the OfType method will only filter through the immediate children of the calling object. makes sense.
sorry for not stating it earlier, the format of my flow document is as follows: flowDoc -> 1 block -> 1 table -> 1 row group -> multiple rows -> multiple cells.
since im trying to cater for multiple cells selected over multiple rows..and the OfType method only looks at the immediate children, i've had to go the for each path as follows:
im calling the method with richtextbox.Selection (as i assume you'd be expecting) and although im getting results now, im getting inaccurate results.
lets say my flow document is made up of a 5 x 5 table, my selection is 2 cells (row 1 cell 1 and row 2 cell 1). my GetSelectedCells function is returning 3 cells (row 1 cell 1, row 1 cell 2, row 2 cell 2). not sure why, im guessing theres some confusion or inaccuracy in the .Selection text pointer being in the wrong position.
any thoughts? also is there maybe a more elegant way of doing this? is it possible of converting this function to use generics(instead of TableCell's) given the hierarchy of the cells/rows/table etc?
cheers
sorry for not stating it earlier, the format of my flow document is as follows: flowDoc -> 1 block -> 1 table -> 1 row group -> multiple rows -> multiple cells.
since im trying to cater for multiple cells selected over multiple rows..and the OfType method only looks at the immediate children, i've had to go the for each path as follows:
Public Function GetSelectedCells(ByVal selection As TextSelection) As List(Of TableCell)
Dim cells As List(Of TableCell) = New List(Of TableCell)
For Each tblRow In rtbTable.RowGroups(0).Rows ' where rtbTable = CType(flowDoc.Blocks(0), Table)
cells.AddRange(tblRow.Cells.OfType(Of TableCell)().Where(Function(w) selection.Contains(w.ContentStart)).ToList)
Next
Return cells
End Function
im calling the method with richtextbox.Selection (as i assume you'd be expecting) and although im getting results now, im getting inaccurate results.
lets say my flow document is made up of a 5 x 5 table, my selection is 2 cells (row 1 cell 1 and row 2 cell 1). my GetSelectedCells function is returning 3 cells (row 1 cell 1, row 1 cell 2, row 2 cell 2). not sure why, im guessing theres some confusion or inaccuracy in the .Selection text pointer being in the wrong position.
any thoughts? also is there maybe a more elegant way of doing this? is it possible of converting this function to use generics(instead of TableCell's) given the hierarchy of the cells/rows/table etc?
cheers
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
hmm..
interestingly enough i initially started with something like that in the first place, however it didnt seem to work as 'selection.Contains(x)' was still getting triggered for cells in between the selected cells from a left-to-right logical view.
i've changed 'w.ContentStart' to 'cell.ConrtentEnd' as 'w' is not longer infered by the compiler and the ContentStart pointer position causes inaccuracies due to the opening tags and next insertion position.
either way the solution works great, many thanks TheLearnedOne :)
interestingly enough i initially started with something like that in the first place, however it didnt seem to work as 'selection.Contains(x)' was still getting triggered for cells in between the selected cells from a left-to-right logical view.
i've changed 'w.ContentStart' to 'cell.ConrtentEnd' as 'w' is not longer infered by the compiler and the ContentStart pointer position causes inaccuracies due to the opening tags and next insertion position.
either way the solution works great, many thanks TheLearnedOne :)