powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Всплывающее окно с затемнением формы
8 сообщений из 8, страница 1 из 1
Всплывающее окно с затемнением формы
    #39044032
Nechto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте!
Помогите пожалуйста разобраться с концепцией. Имею следующую разметку с Frame-ом:
<Window>
<DockPane>

...

<DockPanel DockPanel.Dock="Top">
<Frame x:Name="Browser" NavigationUIVisibility="Hidden" />
</DockPanel>

</DockPanel>
</Window>
В данный Frame я выгружаю различные представления.

Для себя поставил задачу реализовать всплывающее окно, с затемнением основного окна. И когда начал думать как это сделать, я несколько запутался в каком направлении идти.
...
Рейтинг: 0 / 0
Всплывающее окно с затемнением формы
    #39044069
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NechtoЗдравствуйте!
Помогите пожалуйста разобраться с концепцией. Имею следующую разметку с Frame-ом:
<Window>
<DockPane>

...

<DockPanel DockPanel.Dock="Top">
<Frame x:Name="Browser" NavigationUIVisibility="Hidden" />
</DockPanel>

</DockPanel>
</Window>
В данный Frame я выгружаю различные представления.

Для себя поставил задачу реализовать всплывающее окно, с затемнением основного окна. И когда начал думать как это сделать, я несколько запутался в каком направлении идти.
Я делаю по другому.
Для затемнения формы лучше всего использовать Adorner. Само диалоговое окно я сделал как отдельный FrameworkElement, у этого элемента есть 2 свойства Content и ContentTemplate, Content это модель (View Model), ContentTemplate это шаблон DataTemplate.
И свойство IsOpen, а так же CommandBinding для открытия по команде.
В самом диалоговом окно содержимое можно задать в шаблоне, я для обработки нажатия кнопок использовать модель диалогового окна или маршрутизируемые команды (для 2ого, нужно сделать проброс команд из 1 окна в окно из которого открывается).
Затем либо с помощью триггера, либо с помощью Binding'а, либо с помощью Command'ы можно открыть окно. Если открывать через команду можно передать модель в параметрах.
Так же полезно будет создать свойство Style которое будет определять свойства открываемого (диалогового окна)
Как сделать затемнение?
При изменении свойства IsOpen, с помощью LogicalTree находите открытое окно. Это предпоследний элемент дерева, либо искать по типу Window.
Затем создаем свой AdornerDecorator, этот базовый класс от Decorator, который в свою очередь наследуется от FrameworkElement, а значит и Visual. Суть этого элемента в том, что его можно разместить поверх другого контрола (так же как Focus или самый начальный Adorner окна. Внутри разместить Visual элемент с чёрным цветом и полной прозрачностью, а затем с помощью ColorAnimation снижаем прозрачность.
Для производительность поверх черного квадрата можно создать квадрат с кистью VisualBrush, который будет копировать содержимое окна, тогда не будет постоянно видимых элементов управления.
После того как IsOpen снова становится False, мы выполняем обратную анимацию и удаляем Adorner.

Вот так. Код могу дать завтра, дома у меня нет, писать лень :)
...
Рейтинг: 0 / 0
Всплывающее окно с затемнением формы
    #39044548
Nechto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Буду очень признателен за код вашего велосипеда.
А готовые велосипеды от есть?
...
Рейтинг: 0 / 0
Всплывающее окно с затемнением формы
    #39045488
maratoss
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Nechto,

Можно же просто бэкграунд окна сделать прозрачным и черным, вот и будет затемнение
что-то вроде такого:

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        AllowsTransparency="True" WindowStyle="None">
    <Window.Background>
        <SolidColorBrush Opacity="0.5" Color="White"/>
    </Window.Background>
    <Grid>
        <Button Width="200" Height="50">button</Button>
    </Grid>
</Window>



Ну или можешь глянуть сюда http://mahapps.com/ там есть всплывашки
...
Рейтинг: 0 / 0
Всплывающее окно с затемнением формы
    #39051391
Nechto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
maratossNechto,

Можно же просто бэкграунд окна сделать прозрачным и черным, вот и будет затемнение
что-то вроде такого:

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        AllowsTransparency="True" WindowStyle="None">
    <Window.Background>
        <SolidColorBrush Opacity="0.5" Color="White"/>
    </Window.Background>
    <Grid>
        <Button Width="200" Height="50">button</Button>
    </Grid>
</Window>



Ну или можешь глянуть сюда http://mahapps.com/ там есть всплывашки

Этот Dialog у mahapps, тоже самое что и Telerik http://docs.telerik.com/devtools/wpf/controls/radwindow/features/predefined-dialogs
...
Рейтинг: 0 / 0
Всплывающее окно с затемнением формы
    #39051403
Nechto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Просто затемнение для меня мало. Мне нужно чтобы накладывался затемненный прозрачный слой на всю рабочую область окна, тем блокировав все что находится по этим слоем. А на этом слое мне нужен слой в котором я могу отображать контролы.
...
Рейтинг: 0 / 0
Всплывающее окно с затемнением формы
    #39051593
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот вам рабочий пример, за вас делать всё мне лень, разбирайтесь и делайте как вам удобнее.
Лично я использую маршрутизируемые команды и самописный обвес для прослушивания этих команд и вызова соответствующих команд в ViewModel, их я в пример не привёл.
Окно открывается по свойство IsOpen = true, либо по маршрутизируемой команде OpenDialog, которую надо передать в диалог.
Стиль окна задается через WindowStyle, содержимое передается через ContentPresenter (содержимое, шаблонданных)
Затемнение происходит именно так, как вам и нужно (на сколько я понял).
View:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
<Application x:Class="SizeVisualizer.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:sizeVisualizer="clr-namespace:SizeVisualizer"
             xmlns:system="clr-namespace:System;assembly=mscorlib"
             StartupUri="DemoWindow.xaml">
    <Application.Resources>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Width" Value="150"/>
            <Setter Property="Height" Value="32"/>
            <Setter Property="Margin" Value="5" />
        </Style>
        <system:String x:Key="DialogText">
            Здравствуйте!
Помогите пожалуйста разобраться с концепцией. Имею следующую разметку с Frame-ом:
В данный Frame я выгружаю различные представления.
Для себя поставил задачу реализовать всплывающее окно, с затемнением основного окна. И когда начал думать как это сделать, я несколько запутался в каком направлении идти.
        </system:String>
        <sizeVisualizer:MainModel x:Key="MainModel"/>
    </Application.Resources>
</Application>


Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
<Window x:Class="SizeVisualizer.DemoWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:commonControls="clr-namespace:CommonControls;assembly=CommonControls"
        Title="DemoWindow" Height="300" Width="500"
        DataContext="{StaticResource MainModel}">
    <Window.Resources>
        <DataTemplate x:Key="DialogWindowTemplate">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <TextBlock Grid.Row="0" 
                           HorizontalAlignment="Center" VerticalAlignment="Center" 
                           TextWrapping="Wrap"
                           Text="{StaticResource DialogText}"/>
                <StackPanel Grid.Row="1"
                            Orientation="Horizontal" >
                    <Button Content="Ok" IsDefault="True"/>
                    <Button Content="Cancel" IsCancel="True"/>
                </StackPanel>
                
            </Grid>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <commonControls:DialogWindow x:Name="Dialog" Header="Dialog Window"
                                     Content="{Binding Dialog}"
                                     ContentTemplate="{StaticResource DialogWindowTemplate}" Margin="0,-10,0,10">
            <commonControls:DialogWindow.WindowStyle>
                <Style TargetType="{x:Type Window}">
                    <Setter Property="MaxWidth" Value="500"/>
                </Style>
            </commonControls:DialogWindow.WindowStyle>
        </commonControls:DialogWindow>

        <Button VerticalAlignment="Top" HorizontalAlignment="Left"
                Content="Open Dialog"
                Command="{x:Static commonControls:DialogWindow.OpenDialog}"
                CommandTarget="{Binding ElementName=Dialog}"/>
        <TextBox Width="300" VerticalAlignment="Center" HorizontalAlignment="Center"/>
    </Grid>
</Window>


ViewModel:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
namespace SizeVisualizer
{
    public class MainModel
    {
        public string Value { set; get; }

        public MainModel()
        {
            Value = "Example";
        }

        public DialogModel Dialog { set; get; }
    }

    public class DialogModel
    {
        public string Value { set; get; }
    }
}



Control (Theme resource):
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
    <Style TargetType="{x:Type local:DialogWindow}">
        <Setter Property="Template" Value="{x:Null}"/>
    </Style>
    
    <Style TargetType="{x:Type local:DlgWindow}">
        <Setter Property="Background" Value="White"/>
        <Setter Property="BorderBrush" Value="#A0000000"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="ResizeMode" Value="CanResizeWithGrip"/>
        <Setter Property="SizeToContent" Value="WidthAndHeight"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:DlgWindow}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}" 
                            BorderThickness="{TemplateBinding BorderThickness}" 
                            CornerRadius="2" Margin="0,0,5,5">
                        <Border.Effect>
                            <DropShadowEffect Opacity="0.5" Color="{TemplateBinding BorderBrush}" ShadowDepth="5"/>
                        </Border.Effect>
                        <AdornerDecorator>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" x:Name="HeaderRow"/>
                                    <RowDefinition Height="Auto" x:Name="HeaderSeparator"/>
                                    <RowDefinition Height="Auto" x:Name="ContentRow"/>
                                </Grid.RowDefinitions>
                            
                                <!-- HEADER -->
                                <ContentPresenter Content="{TemplateBinding Header}" Grid.Row="0" Margin="14,5" />
                            
                                <Rectangle Height="1" Fill="#E5E5E5" Grid.Row="1"  Margin="14,0"/>
                            
                                <!-- CONTENT -->
                                <ContentPresenter Grid.Row="2" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                            </Grid>
                        </AdornerDecorator>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


Control code:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace CommonControls
{
    public class DialogWindow : ContentControl
    {

        public static ICommand OpenDialog = new RoutedCommand("OpenDialog", typeof (DialogWindow));

        private Popup a;
        private AdornerContainer _adornerContainer;
        private Visual _rootElement;
        private IAnimatable _border;

        public Style WindowStyle
        {
            get { return (Style)GetValue(WindowStyleProperty); }
            set { SetValue(WindowStyleProperty, value); }
        }
        
        public static readonly DependencyProperty WindowStyleProperty =
            DependencyProperty.Register("WindowStyle", typeof(Style), typeof(DialogWindow), new PropertyMetadata(null));
        
        public bool IsOpen
        {
            get { return (bool)GetValue(IsOpenProperty); }
            set { SetValue(IsOpenProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsOpen.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsOpenProperty =
            DependencyProperty.Register("IsOpen", typeof(bool), typeof(DialogWindow), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault , IsOpenChanged));


        private Window _openWindow = null;

        private static void IsOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var dw = (DialogWindow)d;
            var isOpen = (bool) e.NewValue;
            var oldIsOpen = (bool) e.OldValue;
            if (isOpen && !oldIsOpen)
            {
                var window = Window.GetWindow(dw);
                if (window != null)
                {
                    var dialogWindow = new DlgWindow
                    {
                        Header = dw.Header,
                        MinWidth = 50,
                        MinHeight = 50,
                        Owner = window,
                        AllowsTransparency = true,
                        WindowStyle = System.Windows.WindowStyle.None,
                        ResizeMode = ResizeMode.NoResize,
                        WindowStartupLocation = WindowStartupLocation.CenterOwner,
                        DataContext = dw.DataContext,
                        Style = (Style)dw.GetValue(WindowStyleProperty),
                        Content = dw.Content,
                        ContentTemplate = dw.ContentTemplate,
                        ContentTemplateSelector = dw.ContentTemplateSelector
                    };

                    dialogWindow.AddHandler(CommandManager.CanExecuteEvent, new RoutedEventHandler(dw.OnRoutedEvent));
                    dialogWindow.AddHandler(CommandManager.ExecutedEvent, new RoutedEventHandler(dw.OnRoutedEvent));

                    dw.Blur();
                    dw._openWindow = dialogWindow;
                    dialogWindow.ShowDialog();

                    dialogWindow.RemoveHandler(CommandManager.CanExecuteEvent, new RoutedEventHandler(dw.OnRoutedEvent));
                    dialogWindow.RemoveHandler(CommandManager.ExecutedEvent, new RoutedEventHandler(dw.OnRoutedEvent));

                    dialogWindow.DataContext = null;

                    dw.Dispatcher.BeginInvoke(new Action(() => dw.IsOpen = false),
                        System.Windows.Threading.DispatcherPriority.ApplicationIdle);
                    dw.Clear();
                }
            }
            if (!isOpen && oldIsOpen && dw._openWindow != null)
            {
                dw._openWindow.Close();
            }
        }

        #region Animation
        private void Blur()
        {
            //Находим корневой визуальный объект
            var root = VisualTree.FindVisualRoot(this) as Visual;
            //Если это окно, то оно не может иметь Adorner так как у окна он уже есть, по этому находим ContentPresenter этого окна
            if (root is Window) root = VisualTree.FindChild<ContentPresenter>(root);
            if (root == null) return;
            _rootElement = root;
            //Получаем Adorner
            var adornerLayer = AdornerLayer.GetAdornerLayer(root);
            //Если адорнер всё равно не найден, просто не затемняем
            if (adornerLayer == null) return;
            //Создаем контейнер
            if (_adornerContainer == null)
            {
                _border = new Border
                {
                    Background = new SolidColorBrush(Colors.Black),
                    Opacity = 0.0
                };
                _adornerContainer = new AdornerContainer((UIElement)root) { Child = (UIElement)_border };
            }
            adornerLayer.Add(_adornerContainer);

            var animation = new DoubleAnimation
            {
                To = 0.5,
                Duration = TimeSpan.FromSeconds(0.3)
            };
            _border.BeginAnimation(OpacityProperty, animation);
        }


        private void Clear()
        {
            var animation = new DoubleAnimation
            {
                To = 0.0,
                Duration = TimeSpan.FromSeconds(0.3)
            };
            //По завершению анимации удаляем Adorner и удаляем все 
            animation.Completed += animation_Completed;
            _border.BeginAnimation(OpacityProperty, animation);
        }

        void animation_Completed(object sender, EventArgs e)
        {
            if (_rootElement != null)
            {
                var adornerLayer = AdornerLayer.GetAdornerLayer(_rootElement);
                if (_adornerContainer != null)
                {
                    adornerLayer.Remove(_adornerContainer);
                    _adornerContainer = null;
                    _border = null;
                }
                _rootElement = null;
            }
        }
        #endregion

        public object Header
        {
            get { return (object)GetValue(HeaderProperty); }
            set { SetValue(HeaderProperty, value); }
        }

        public static readonly DependencyProperty HeaderProperty =
            DependencyProperty.Register("Header", typeof(object), typeof(DialogWindow), new PropertyMetadata(null));

        static DialogWindow()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DialogWindow), new FrameworkPropertyMetadata(typeof(DialogWindow)));
            FocusableProperty.OverrideMetadata(typeof(DialogWindow), new FrameworkPropertyMetadata(false));
        }

        public DialogWindow()
        {
            CommandBindings.Add(new CommandBinding(OpenDialog, OnOpenDialog));
        }

        private void OnOpenDialog(object sender, ExecutedRoutedEventArgs e)
        {
            IsOpen = true;
        }

        private void OnRoutedEvent(object sender, RoutedEventArgs e)
        {
            if (!e.Handled) RaiseEvent(e);
        }

    }
}


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;

namespace CommonControls
{
    public class DlgWindow : Window
    {


        public object Header
        {
            get { return (object)GetValue(HeaderProperty); }
            set { SetValue(HeaderProperty, value); }
        }
        public static readonly DependencyProperty HeaderProperty =
            DependencyProperty.Register("Header", typeof(object), typeof(DlgWindow), new PropertyMetadata(null));


        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);
            DragMove();
        }

        static DlgWindow()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DlgWindow), new FrameworkPropertyMetadata(typeof(DlgWindow)));
        }
        
        public IEnumerable<ICommand> Commands
        {
            get { return (IEnumerable<ICommand>)GetValue(CommandsProperty); }
            set { SetValue(CommandsProperty, value); }
        }

        public static readonly DependencyProperty CommandsProperty =
            DependencyProperty.Register("Commands", typeof(IEnumerable<ICommand>), typeof(DlgWindow), new PropertyMetadata(null));

        
    }
}




будут вопросы, пишите
...
Рейтинг: 0 / 0
Всплывающее окно с затемнением формы
    #39052717
maratoss
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NechtoПросто затемнение для меня мало. Мне нужно чтобы накладывался затемненный прозрачный слой на всю рабочую область окна, тем блокировав все что находится по этим слоем. А на этом слое мне нужен слой в котором я могу отображать контролы.

Вот прозрачный затемненный фон, который блокирует все что сзади и непрозрачные контролы на нем, по которым можно щелкать.
Или я неправильно понял?
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Всплывающее окно с затемнением формы
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]