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?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
Bob LearnedCommented:
How are you building the content for the RichTextBox?  The usual assumption is a FlowDocument...
0
Exploring ASP.NET Core: Fundamentals

Learn to build web apps and services, IoT apps, and mobile backends by covering the fundamentals of ASP.NET Core and  exploring the core foundations for app libraries.

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
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.