В Silverlight есть замечательный класс ChildWindow, основная проблема с этим классом заключается в том, что это ни разу не Window. У него нет свойств Left, Top или X, Y... Это вообще Grid, который кладется в Z-буфер самым верхним, и закрывает доступ ко всему, что ниже, а потом уже рисуется контрол, который похож на окно. В чем проблема и как решать подкатом.
Сначала о проблеме. У нас написан универсальный метод который позволяет показать произвольный компонент в "модальном окне", причем размеры окна подстраиваются под под размеры компонента. Окно показывает кнопки принять/отмена реализует сервис по применению биндинга в переданном компоненте по кнопке принять и т.д. Проблема возникает когда компонент меняет свои размеры после того, как был показан. Окно расширяется, а левый верхний угол остается на месте.
До изменения размера:
После изменения размера:
Радостной новостью оказалось, что в ChildWindow мы помещаем Grid, у которого есть событие изменения размера. Собственно на него и приходиться подписать вот такой обработчик:
Собственно обработчик изменения размера нашего грида:
Правда жуть?
Сначала о проблеме. У нас написан универсальный метод который позволяет показать произвольный компонент в "модальном окне", причем размеры окна подстраиваются под под размеры компонента. Окно показывает кнопки принять/отмена реализует сервис по применению биндинга в переданном компоненте по кнопке принять и т.д. Проблема возникает когда компонент меняет свои размеры после того, как был показан. Окно расширяется, а левый верхний угол остается на месте.
До изменения размера:
После изменения размера:
Радостной новостью оказалось, что в ChildWindow мы помещаем Grid, у которого есть событие изменения размера. Собственно на него и приходиться подписать вот такой обработчик:
public static void ShowModal(FrameworkElement p_controlForShow, Action<bool> p_closeAction, ShowModalButton p_buttons = ShowModalButton.ApplyCancel, string p_closeButton = "Отмена", string p_applyButton = "Принять", string p_Title = "") { // Технология следующая, показываем Grid, // в него контрол который передал пользователь, плюс кнопки принять и отмена // Если пользователь нажимает принять, то в контрол передаем принять изменения ChildWindow ch = new ChildWindow(); ch.Title = p_Title; Grid modalGrid = new Grid(); #region Настройка Grid modalGrid.SizeChanged += (s, e) => { modalGrid_SizeChanged(ch, e); }; ...
Собственно обработчик изменения размера нашего грида:
static void modalGrid_SizeChanged(object sender, SizeChangedEventArgs e) { FrameworkElement ch = sender as FrameworkElement; if (ch != null) { double height = Application.Current.Host.Content.ActualHeight - 40 > 0 ? Application.Current.Host.Content.ActualHeight - 40 : 300; double width = Application.Current.Host.Content.ActualWidth - 40 > 0 ? Application.Current.Host.Content.ActualWidth - 40 : 450; if (width != 0 && height != 0) { Application.Current.RootVisual.Dispatcher.BeginInvoke ( () => { FrameworkElement root = (FrameworkElement)VisualTreeHelper.GetChild (сh, 0); FrameworkElement contentroot = root.FindName("ContentRoot") as FrameworkElement; double x = (Application.Current.Host.Content.ActualWidth - width) / 2; double y = (Application.Current.Host.Content.ActualHeight - height) / 2; if (contentroot != null) { TransformGroup group = contentroot.RenderTransform as TransformGroup; if (group != null) { TranslateTransform translateTransform = null; foreach (var transform in group.Children.OfType<TranslateTransform>()) { translateTransform = transform; } if (translateTransform != null) { // reset transform translateTransform.X = 0.0; translateTransform.Y = 0.0; } } } } ); } } }
Правда жуть?
Комментариев нет:
Отправить комментарий