Adventures in Silverlight 4: Richtextboxes and DataGrids
I've had to discover the wonders of the RichTextBox in Silverlight 4. Here's the worst thing about it: it's practically all native code. The stacktraces mean nothing as they usually soon disappear into a native call. So breaking execution or looking at Reflector does not help much.
The RichTextBox control is also not quite there. While I'm very thankful for how it handles many MANY languages. I've ran into a few problems that are major bugs. The biggest, by far, is one that only happens in very specific yet not uncommon cases.
The bug must be some infinite loop in native code (since I can't see anything happen when I break execution) since CPU maxes out when it happens. To get this to happen, I have to do the following: put the RTB in a DataGrid to display text in the rows, make the RTB be in RightToLeft, use InlineUIContainers, then start sizing the browser window. Certain cases cause the CPU to just spin in the MeasureOverride method with these conditions.
Another problem, specifically with the DataGrid itself, is that it's Rows don't auto-shrink. There are tons of posts about it:
http://forums.silverlight.net/forums/p/160830/375007.aspx
http://forums.silverlight.net/forums/t/71184.aspx
http://forums.silverlight.net/forums/p/133177/299525.aspx
http://forums.silverlight.net/forums/p/123169/277437.aspx
The only reliable fixes for me, so far are:
A) Forcing a resizing of RowHeight programmatically:
datagrid1.RowHeight = 10;
Dispatcher.BeginInvoke(delegate
{
datagrid1.RowHeight = double.NaN;
});
B) Changing the CellStyle of the DataGrid to have the Template's root Grid have a Top VerticalAlignment.
Even if I report the RTB problem, it won't be fixed until SL5 or be ignored/unsolved just like the DataGrid row sizing.
Update:
Using the B strategy (which is the best because A uses way too many resources) you also need to listen to the SizeChanged event of the control in the row that should govern the size. In my case, it is the RichTextBox. On SizeChanged, you need to get the DataGridCellsPresenter and set the height of the Presenter to the ActualHeight of the control. Like so:
RichTextBox control = sender as RichTextBox;
DataGridCell cell = control.Parent as DataGridCell;
DataGridCellsPresenter presenter = cell.Parent as DataGridCellsPresenter;
presenter.Height = control.ActualHeight;