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
gem56Asked:
Who is Participating?
 
Bob LearnedCommented:
Try something a little more old school:

Public Function GetSelectedCells(ByVal selection As TextSelection) As List(Of TableCell)

        Dim selectedCells As List(Of TableCell) = New List(Of TableCell)

        For Each row In rtbTable.RowGroups(0).Rows     
            For Each cell In row.Cells
                  If selection.Contains(w.ContentStart) Then
                       selectedCells.Add(cell)
                  End If
            Next cell        
        Next row

        Return selectedCells

    End Function

Open in new window

0
 
CodeCruiserCommented:
I would suggest you to use the Request Attention button and ask moderators to add the "WPF and Silverlight" zone to your question.
0
 
gem56Author Commented:
done, cheers mate.
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

 
Bob LearnedCommented:
How are you building the content for the RichTextBox?  The usual assumption is a FlowDocument...
0
 
gem56Author Commented:
Hello TheLearnedOne,

yes the content is contained within a flow document.
0
 
Bob LearnedCommented:
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(FlowDocument document, TextSelection selection)
        {
            return document.Blocks.OfType<Paragraph>().Where(w => selection.Contains(w.ContentStart)).ToList();
        }
0
 
gem56Author Commented:
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.

    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

Open in new window


any ideas?
cheers
0
 
Bob LearnedCommented:
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.ContentStart)).ToList()
0
 
gem56Author Commented:
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:

    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

Open in new window


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
0
 
gem56Author Commented:
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 :)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.