Иногда вредные пользователи открывают окно с silverlight приложением в фоне.
В отдельной табке, например.
В этом случае некоторый наш код инициализации в контролах столкнется, к примеру, со значениями ActualWidth и ActualHeight = 0, отсутствием некоторых контролов в дереве и прочими косяками.
Возможно, есть красивый способ решить эту проблему, но я его пока не нашел.
Поэтому опишу свой.
Предположим, у нас есть контрол MyPanel, в котором есть метод void CalcSomething(), которому позарез нужно высчитать что-то хитрое основываясь на текущих размерах контрола.
1. Добавляем поле
private readonly ManualResetEvent layout_complete = new ManualResetEvent( false );
2. В конструкторе MyPanel подписываемся на SizeChanged:
SizeChanged += on_size_changed;
3. В обработчике события смотрим, посчитан ли уже размер для нашего контрола:
private void on_size_changed( object sender, SizeChangedEventArgs e )
{
if (ActualHeight != 0 && ActualWidth != 0)
_layout_complete.Set();
}
4. Если раньше наш метод CalcSomething вызывался просто, теперь он должен стартовать в отдельном потоке:
new Thread(CalcSomething).Start();
5. Исполнение CalcSomething отложим до момента, когда будет послан сигнал через _layout_complete:
private void CalcSomething()
{
_layout_complete.WaitOne()
...старый код работы с UI...
6. И стоит учитывать, что поскольку мы теперь находимся в отдельном потоке, работать с UI напрямую нельзя.
private void CalcSomething()
{
_layout_complete.WaitOne()
Deployment.Current.Dispatcher.BeginInvoke( () =>
{
...старый код работы с UI...
} );
}
Комментариев нет:
Отправить комментарий