Surendra Shrestha
Surendra Shrestha

Reputation: 1080

How can I set width and height in custom pop up in prism?

The problem statement is:

I am using custom pop up in my wpf project. I am able to use custom pop up with custom user control. There I can provide width and height in the user control property and the pop window size is also as defined. But the problem is when I resize the pop up window, the extra place is filled with empty space, but I have set the custom control as grid and set to be resized accordingly. But if I do not set the width and height in custom control the resized works perfectly fine. My question is: is there any way I can tell the prism to set window size as defined in the user control it is being populated.

Any help is greatly appreciated.

This is used in shell property:

    <Window x:Class="TestApp.Shell"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:prism="http://prismlibrary.com/"
xmlns:inf="clr-namespace:Application.Infrastructure;assembly=Application.Infrastructure"
        xmlns:infBehaviors="clr-Application.Infrastructure.Behaviors;assembly=Application.Infrastructure"
            infBehaviors:RegionPopupBehaviors.CreatePopupRegionWithName="{x:Static inf:RegionNames.SecondaryRegion}"
            infBehaviors:RegionPopupBehaviors.ContainerWindowStyle="{StaticResource WindowRegionStyle}"
            mc:Ignorable="d" Title="Title here"  WindowState="Maximized"
            WindowStyle="ThreeDBorderWindow" Background="#e5f8ff" Icon="Resources/favicon.ico">

Below is infBehaviors class

using Microsoft.Practices.ServiceLocation;
using Prism.Regions;
using System;
using System.ComponentModel;
using System.Windows;

namespace Application.Infrastructure.Behaviors
{
    /// <summary>
    /// Declares the Attached Properties and Behaviors for implementing Popup regions.
    /// </summary>
    /// <remarks>
    /// Although the fastest way is to create a RegionAdapter for a Window and register it with the RegionAdapterMappings,
    /// this would be conceptually incorrect because we want to create a new popup window everytime a view is added 
    /// (instead of having a Window as a host control and replacing its contents everytime Views are added, as other adapters do).
    /// This is why we have a different class for this behavior, instead of reusing the <see cref="RegionManager.RegionNameProperty"/> attached property.
    /// </remarks>
    public static class RegionPopupBehaviors
    {
        /// <summary>
        /// The name of the Popup <see cref="IRegion"/>.
        /// </summary>
        public static readonly DependencyProperty CreatePopupRegionWithNameProperty =
            DependencyProperty.RegisterAttached("CreatePopupRegionWithName", typeof(string), typeof(RegionPopupBehaviors), new PropertyMetadata(CreatePopupRegionWithNamePropertyChanged));

        /// <summary>
        /// The <see cref="Style"/> to set to the Popup.
        /// </summary>
        public static readonly DependencyProperty ContainerWindowStyleProperty =
          DependencyProperty.RegisterAttached("ContainerWindowStyle", typeof(Style), typeof(RegionPopupBehaviors), null);

        /// <summary>
        /// Gets the name of the Popup <see cref="IRegion"/>.
        /// </summary>
        /// <param name="owner">Owner of the Popup.</param>
        /// <returns>The name of the Popup <see cref="IRegion"/>.</returns>
        public static string GetCreatePopupRegionWithName(DependencyObject owner)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }

            return owner.GetValue(CreatePopupRegionWithNameProperty) as string;
        }

        /// <summary>
        /// Sets the name of the Popup <see cref="IRegion"/>.
        /// </summary>
        /// <param name="owner">Owner of the Popup.</param>
        /// <param name="value">Name of the Popup <see cref="IRegion"/>.</param>
        public static void SetCreatePopupRegionWithName(DependencyObject owner, string value)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }

            owner.SetValue(CreatePopupRegionWithNameProperty, value);
        }

        /// <summary>
        /// Gets the <see cref="Style"/> for the Popup.
        /// </summary>
        /// <param name="owner">Owner of the Popup.</param>
        /// <returns>The <see cref="Style"/> for the Popup.</returns>
        public static Style GetContainerWindowStyle(DependencyObject owner)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }

            return owner.GetValue(ContainerWindowStyleProperty) as Style;
        }

        /// <summary>
        /// Sets the <see cref="Style"/> for the Popup.
        /// </summary>
        /// <param name="owner">Owner of the Popup.</param>
        /// <param name="style"><see cref="Style"/> for the Popup.</param>
        public static void SetContainerWindowStyle(DependencyObject owner, Style style)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }

            owner.SetValue(ContainerWindowStyleProperty, style);
        }

        /// <summary>
        /// Creates a new <see cref="IRegion"/> and registers it in the default <see cref="IRegionManager"/>
        /// attaching to it a <see cref="DialogActivationBehavior"/> behavior.
        /// </summary>
        /// <param name="owner">The owner of the Popup.</param>
        /// <param name="regionName">The name of the <see cref="IRegion"/>.</param>
        /// <remarks>
        /// This method would typically not be called directly, instead the behavior 
        /// should be set through the Attached Property <see cref="CreatePopupRegionWithNameProperty"/>.
        /// </remarks>
        public static void RegisterNewPopupRegion(DependencyObject owner, string regionName)
        {
            // Creates a new region and registers it in the default region manager.
            // Another option if you need the complete infrastructure with the default region behaviors
            // is to extend DelayedRegionCreationBehavior overriding the CreateRegion method and create an 
            // instance of it that will be in charge of registering the Region once a RegionManager is
            // set as an attached property in the Visual Tree.
            IRegionManager regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
            if (regionManager != null)
            {
                IRegion region = new SingleActiveRegion();
                DialogActivationBehavior behavior;
                behavior = new WindowDialogActivationBehavior();
                behavior.HostControl = owner;

                region.Behaviors.Add(DialogActivationBehavior.BehaviorKey, behavior);
                regionManager.Regions.Add(regionName, region);
            }
        }

        private static void CreatePopupRegionWithNamePropertyChanged(DependencyObject hostControl, DependencyPropertyChangedEventArgs e)
        {
            if (IsInDesignMode(hostControl))
            {
                return;
            }

            RegisterNewPopupRegion(hostControl, e.NewValue as string);
        }

        private static bool IsInDesignMode(DependencyObject element)
        {
            // Due to a known issue in Cider, GetIsInDesignMode attached property value is not enough to know if it's in design mode.
            return DesignerProperties.GetIsInDesignMode(element) || Application.Current == null
                   || Application.Current.GetType() == typeof(Application);
        }
    }
}

I call the popup with the below code:

_regionManager.Regions[RegionNames.MainRegion].RequestNavigate("/AppSettingsView");

Upvotes: 0

Views: 931

Answers (1)

Glenn Keates
Glenn Keates

Reputation: 131

I appreciate this question is pretty old but hopefully this will help anyone trying to do the same thing!

Within the prism library, you have access to a feature called the dialog service which allows you to easily call pop up windows and have full access over their window properties.

In order to create register a dialog, create a module and use the container registry to register it as a dialog. The view model that you use must inherit IDialogAware in order to work.

 containerRegistry.RegisterDialog<View, ViewModel>("DialogName");

And then to open the dialog from anywhere

dialogService.ShowDialog("DialogName")

When using this pattern, you are able to set the properties of the window using the prism:Dialog.WindowStyle tag within your user control

<UserControl x:Class="TestApp.Shell"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
       xmlns:prism="http://prismlibrary.com">
   <prism:Dialog.WindowStyle>
       <Style TargetType="Window">
           <Setter Property="ResizeMode" Value="NoResize" />
           <Setter Property="Width" Value="880" />
           <Setter Property="Height" Value="780" />
       </Style>
   </prism:Dialog.WindowStyle>
</UserControl>

You are able to use extra parameters to your dialog calls in order to transfer data to and from your dialog, which is covered in the documentation for the dialog service here

Upvotes: 3

Related Questions