1

И так из названия думаю понятно, мне нужно открыть окно внутри окна, есть MainWindow, и SecondWindow, мне нужно открыть SecondWindow в MainWindow. Т.е внутри него, как это сделать? Я как только не пытался, и .ShowDialog(), и устанавливал owner - оно все равно открывает как новое окно, т.е не внутри MainWindow. Помогите пожалуйста, уже пол дня гуглю.

Я пробовал такой дикий костыль, который работает, но криво, да он перекрывает форму так как надо, делая иллюзию что действительно окно в окне, но если я вынесу основное окно приложения за край и открою свое псевдо-модальное окно то оно станет на координаты 0 по той плоскости в которой основное окно вышло в минус. Т.е координаты окна основного -25, 300, т.е оно ушло на 25 влево за край экрана, а псевдо-модальное окно будет на 0, 300. Вот код которым я делал костыли из флешек:

        var secondWindow = new SecondWindow();

        var x = Left;
        var y = Top;

        secondWindow.MaxHeight = Height;
        secondWindow.MaxWidth = Width;

        secondWindow.Owner = this;

        secondWindow.ShowDialog();

        secondWindow.Left = x;
        secondWindow.Top = y;
  • А какой смысл в этом? Можно скрин того, что вы хотите? Ибо окно в окне не очень хорошее решение, а если вы хотите показать другой контент, то там это явно не окнами делается. Если же вам надо сделать всплывающее окно, то сделайте PopUp или что то на подобие, некий контрол поверх остального. – EvgeniyZ Jun 29 '18 at 17:03
  • @EvgeniyZ Конечно, держите ссылки на скриншоты. Как было и как стало. ссылка / Отвечаю на смысл - так удобнее и как то по нормальному, чем окно на полный экран, ну на скринах видно, что действительно модальное лучше чем на полный экран, да и оно затемняет полный экран, а так только программу. Некий контрол? Не знаю, думаю сначала подумать над тем что бы сделать это в окне. :) – Pavel Erokhin Jun 29 '18 at 17:08

1 Answers1

6

Подобные вещи делаются не окнами, а контролами. Создадим допустим самый простой контрол:

  • Жмем на проекте ПКМ - Добавить - Пользовательский элемент управление - задаем имя.
  • Так, как нам надо отображать что то внутри, то пусть это будет ContentControl, а не UserControl. Заменяем в XAML UserControl на ContentControl, а также в cs файле меняем тоже на ContentControl.
  • Далее в XAML давайте зададим шаблон нашему контролу:

    <ContentControl.Template>
        <ControlTemplate TargetType="ContentControl">
            <Grid Background="#7f000000">
                <Grid Background="White" HorizontalAlignment="Center" VerticalAlignment="Center">
                    <StackPanel Margin="20">
                        <TextBlock Text="{Binding Text, ElementName=popup}" FontSize="20" />
                        <ContentPresenter />
                    </StackPanel>
                </Grid>
            </Grid>
        </ControlTemplate>
    </ContentControl.Template>
    
  • Ну и зададим имя: x:Name="popup".

  • Осталось создать DependencyProperty для текста, добавляем в cs файле контола что то вроде этого:

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
        "Text", typeof(string), typeof(PopUpControl), new PropertyMetadata(default(string)));
    
    public string Text
    {
        get => (string) GetValue(TextProperty);
        set => SetValue(TextProperty, value);
    }
    
  • Все, имея это можем тестировать, допустим я сделаю некий контент и поверх него выведу наш контрол, внутрь которого помещаю кнопку:

    <Grid>
        <StackPanel Margin="5">
            <TextBlock Text="Текст..." Margin="5"/>
            <Button Content="Некая кнопка" Margin="5"/>
            <TextBox Text="Напиши что то..."/>
        </StackPanel>
        <local:PopUpControl Text="Привет мир!">
            <Button Content="111" Width="60" Height="20"/>
        </local:PopUpControl>
    </Grid>
    
  • Запускаем и смотрим:

Result

Собственно и вся магия, вам лишь нужно сделать свой дизайн "окна", дизайн "внутренностей", свои DependencyProperty ну и функционал открытия/закрытия.

EvgeniyZ
  • 15,694
  • Спасибо, решение внушительное, и не такое сложное. :) – Pavel Erokhin Jun 29 '18 at 17:47
  • Все работает, только что доделал. :) – Pavel Erokhin Jun 29 '18 at 18:20
  • @MairwunNx Вот и супер. Тут может быть небольшая проблема с ошибкой в дизайнере, решить ее можно поменяв тип на TargetType="ContentControl". Ну а вообще, запомните на будущее, что в WPF (да и не только) то, что вы перетаскиваете мышью, имеет функции открытия/закрытия и сворачивания - это окно, а то, что внутри этого окна - это контролы. Что касательно окна в окне, то это уже MDI интерфейс (это что то вроде вкладок в Visual Studio). – EvgeniyZ Jun 29 '18 at 20:14
  • У меня почему-то когда есть TargetType="local:PopUpControl" выдает ошибку, а если удалить, то тогда работает, но кнопку 111 не отображает. Что это может быть? – Bulson Jun 29 '18 at 21:09
  • @Bulson Коментом выше ответил. – EvgeniyZ Jun 29 '18 at 21:22
  • @EvgeniyZ ага, так работает. – Bulson Jun 29 '18 at 21:46
  • @EvgeniyZ | Конечно. Про MDI слышал, но как то не хочется это в WPF, лучше либо Page либо Контрол как вы предложили. – Pavel Erokhin Jun 30 '18 at 08:05