Всплывающее окно в стиле лайтбокса в WPF как?

(Я пытаюсь изучить WPF с помощью руководств и документации, а также пытаюсь разработать пользовательский интерфейс для своего бэкэнд-полного приложения, пока говорю. Я слышал, как люди говорят, что кривая обучения довольно крутая. Но иногда мне интересно, что Я пытаюсь сделать то, что на самом деле сложно сделать в WPF, или, если это просто, но я думаю неправильно, или, если нет, это довольно просто, но я просто не знаю, как это сделать.)

Вот мой текущий вопрос. Я хотел, чтобы щелчок по какой-либо части моего пользовательского интерфейса открывал «всплывающее окно», где пользователь мог ввести дополнительную информацию. Я бы хотел, чтобы всплывающее окно было в стиле лайтбокса, то есть всплывающее окно является модальным по отношению к странице, затемняет остальную часть страницы, чтобы стать центром внимания и т. Д. Они обычно встречаются на веб-сайтах.

Немного поисков привело меня к элементу управления WPF Popup. Я добавил его, поместил в него свой контент, установил для свойства IsOpen значение True и - готово! Всплывающее окно. Затем я добавил невидимый прямоугольник, который покрывает все мое окно, и также установил для него значение «Видимый», когда я хочу, чтобы всплывающее окно открывалось. Здорово!

Итак, теперь я хотел сделать это динамически, потому что иногда я загружаю запись, для которой иногда потребуется открыть другой элемент управления (UserControl) во всплывающем окне для редактирования информации о нем. Поэтому я создал себе метод под названием OpenPopup. Но я не могу найти способ написать этот метод с использованием WPF. В Windows Forms я бы написал: (я использую VB.NET)

Sub ShowPopup (form as Form, ctrl as Control)
    'Create 'rect' as new dark rectangle control
    'Z-order it to the top
    'form.Controls.Add 'rect'
    'form.Controls.Add ctrl
    'Z-order 'ctrl' to the top
    'Center 'ctrl'
    'Set focus to it
End Sub

Но с WPF у меня возникают проблемы:

1) Я не могу добавить его в окно WPF, потому что у него уже есть дочерний элемент.

2) Если этот дочерний элемент - Canvas, это неплохо. Я могу это обнаружить и добавить на холст. Мне нужно найти способ установить его свойства Left, Top и т. Д., А также Width и Height, поскольку они не кажутся свойствами элемента управления Rectangle, а скорее расширяются объектом Canvas - в XAML они называются Cavnas.Top и т.д., но Intellisense не показывает их, когда я пытаюсь использовать его в коде.

3) А если это StackPanel? Тогда мой прямоугольник будет просто уложен под другими элементами управления! И не прикрывая их! Это можно обойти?

4) А если в окне всего один элемент управления и вообще нет элемента управления контейнера?

5) Думаю, проблем, с которыми я столкнулся, было больше. Но начнем с этого.

Заранее спасибо за помощь.


person Fred    schedule 24.03.2011    source источник


Ответы (1)


1) Я не могу добавить его в окно WPF, потому что у него уже есть дочерний элемент.

Ах, зло кодового программирования. Решение состоит не в том, чтобы добавить его в визуальное дерево, а в том, чтобы поместить его в визуальное дерево, готовое и ожидающее нападения, но скрыть его от поля зрения пользователя.

Вот образец, который вы можете бросить в Kaxaml, который демонстрирует суть дела. Установите для видимости сетки лайтбокса значение «Скрытый», чтобы получить доступ к скрытому содержимому.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Viewbox>
            <TextBox Text="SIMULATING CONTENT" />
        </Viewbox>
        <Grid x:Name="Lightbox" Visibility="Visible">
            <Rectangle Fill="Black" Opacity=".5"/>
            <Border
                Margin="100"
                Background="white"
                BorderBrush="CornflowerBlue"
                BorderThickness="4"
                CornerRadius="20">
                <Viewbox Margin="25">
                    <TextBox Text="SIMULATING LIGHTBOX"/>
                </Viewbox>
            </Border>
        </Grid>
    </Grid>
</Page>

2) (снип) Intellisense не показывает их, когда я пытаюсь использовать его в коде.

Canvas.Top etal - это Присоединенные свойства. Присоединенные свойства чрезвычайно удобны и просты в использовании в XAML, но они очень запутаны и их трудно использовать из кода. Еще одна причина, почему программный код - это зло.

3) А если это StackPanel? Тогда мой прямоугольник будет просто уложен под другими элементами управления! И не прикрывая их! Это можно обойти?

Я перенаправляю вас обратно на 1. В WPF также есть много других контейнерных элементов управления. Вы должны изучить их и понаблюдать за тем, как они управляют макетом. Например, я использовал сетку не для того, чтобы использовать ее способность блокировать разделы пользовательского интерфейса для элементов управления, а для ее способности накладывать элементы управления друг на друга и растягивать их до максимального доступного размера для доступного пространства. (окна просмотра предназначены только для масштабирования элементов управления, а не для их растягивания).

4) А если в окне всего один элемент управления и вообще нет элемента управления контейнера?

Корневой элемент окна почти всегда будет контейнерным элементом управления. Но вы контролируете это, поэтому, если вам нужно добавить элементы управления в визуальное дерево во время выполнения, вы можете легко убедиться, что дочерний элемент окна является контейнерным элементом управления, с которым вы можете иметь дело.

5) Думаю, проблем, с которыми я столкнулся, было больше. Но начнем с этого.

Без шуток. Мое предложение номер один для людей в вашей ситуации - бросить то, что вы делаете, и узнать о MVVM. Model-View-ViewModel - это очень простой способ кодирования приложений WPF, который использует многие функции WPF - привязку данных, шаблоны, команды и т.д. ), но в классах, которые легко создавать и тестировать.

person Community    schedule 24.03.2011
comment
+1, особенно за последний абзац. Подход OP к изучению WPF кажется разумным - это тот же подход, что и я, но это действительно хороший способ провести пару разочаровывающих месяцев, в течение которых вы очень мало узнаете о WPF. - person Robert Rossney; 24.03.2011
comment
Спасибо всем! @Will, re # 1: мой вопрос был задан в качестве предпосылки, можно ли сделать это глобально для повторного использования в любом окне без добавления XAML или чего-либо еще. Разве это не преимущество? Re: MVVM и @Robert, спасибо за подсказку. Я согласен, я исследовал MVVM, и мне он действительно очень нравится; Я обязательно продолжу идти по этому пути. Хотя, согласитесь, это не решит проблему, размещенную здесь. - person Fred; 27.03.2011
comment
@user хорошо, это предполагает, что ваш оверлей должен быть инкапсулирован в пользовательский элемент управления. Создание фактического элемента управления, который взаимодействует с пользовательским интерфейсом через код, экспоненциально сложнее ... - person ; 27.03.2011