3

In my Prism 6 WPF MVVM application I use the following PrismUserControl WPF for displaying of modal notification dialogs:

<UserControl x:Class="CommonWpfControlLibrary.NotificationDialogPopupView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
         xmlns:prism="http://prismlibrary.com/"             
         prism:ViewModelLocator.AutoWireViewModel="True"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" MaxHeight="300" MaxWidth="600">

    <StackPanel Orientation="Vertical" Margin="20">
        <TextBlock Text="{Binding Message}" TextWrapping="Wrap"/>
        <telerik:RadButton Content="OK" Command="{Binding OnOkPressedCommand}" HorizontalAlignment="Center" Width="50" Margin="0 10 0 0"/>
    </StackPanel>
</UserControl>

In the Views where I use this UserControl as a modal dialog content I define it as following:

<i:Interaction.Triggers>
    <prism:InteractionRequestTrigger SourceObject="{Binding NotificationRequest, Mode=OneWay}">
        <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True">
            <prism:PopupWindowAction.WindowContent>
                <commonControls:NotificationDialogPopupView/>
            </prism:PopupWindowAction.WindowContent>
        </prism:PopupWindowAction>
    </prism:InteractionRequestTrigger>
</i:Interaction.Triggers>

When I activate the dialog it is displayed, for example, as the following: enter image description here

But as you can see 'Minimize', 'Maximize' and 'Close' buttons are visible and enabled. And the system menu (activated in upper left corner of the dialog) is enabled too. How can I hide 'Minimize', 'Maximize' and 'Close' buttons and disable the system menu?

Prohor
  • 141
  • 1
  • 3
  • 12

5 Answers5

2

I found two solutioins :

1.Disable all windows property :

Set the Window.WindowStyle property to WindowStyle.None

2.Disabling buttons:

I. Disabling Minimize, Maximize buttons :
This can be achieved by setting Window.ResizeMode property to ResizeMode.NoResize. It will disable the minimize and maximize buttons. Furthermore, the window will not resize by mouse click+drag.

II. Not showing Icon and Close button:
Unfortunately, this feature is not available in WPF. To achieve this, you can try setting the WS_EX_DLGMODALFRAME window style by calling [Get/Set]WindowLong (pInvoking in to Win32) from the SourceInitialized event on the Window class.

Community
  • 1
  • 1
Yiao SUN
  • 908
  • 1
  • 8
  • 26
  • UserControl WPF has no WindowStyle and ResizeMode properties. – Prohor Aug 31 '16 at 13:10
  • 1
    `ResizeMode="NoResize" ` in the window property or `this.ResizeMode = System.Windows.ResizeMode.NoResize;` in the file .cs ???? User control can load in the window no ? @Prohor – Yiao SUN Aug 31 '16 at 13:23
  • The userControl is just a view and you load it in your window Check this pls http://stackoverflow.com/a/36042795/6773405 @Prohor – Yiao SUN Aug 31 '16 at 13:31
  • 1
    I did this way: It works. – Prohor Aug 31 '16 at 13:59
  • Yiao Sun, shell you write in more detail about hiding 'Close' button, icon and system menu in the modal dialog? – Prohor Sep 01 '16 at 05:02
2

@Evangelink was close. You would use the WindowStyle property, but you must supply an actual Style. Something like:

<Style TargetType="{Window}">
     <Setter Property="" Value="" />
</Style>
1

2.Disabling close buttons:

Not showing Icon and Close button: Unfortunately, this feature is not available in WPF. To achieve this, you can try setting the WS_EX_DLGMODALFRAME window style by calling [Get/Set]WindowLong (pInvoking in to Win32) from the SourceInitialized event on the Window class. Check this:

public partial class MainWindow : Window
{

[DllImport("user32.dll")]
static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll")]
static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);



const uint MF_BYCOMMAND = 0x00000000;
const uint MF_GRAYED = 0x00000001;
const uint MF_ENABLED = 0x00000000;

const uint SC_CLOSE = 0xF060;

const int WM_SHOWWINDOW = 0x00000018;
const int WM_CLOSE = 0x10;

public MainWindow()
{
    InitializeComponent();
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{

}

protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);

    HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;

    if (hwndSource != null)
    {
        hwndSource.AddHook(new HwndSourceHook(this.hwndSourceHook));
    }
}


IntPtr hwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    if (msg == WM_SHOWWINDOW)
    {
        IntPtr hMenu = GetSystemMenu(hwnd, false);
        if (hMenu != IntPtr.Zero)
        {
            EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
        }
    }
    else if (msg == WM_CLOSE)
    {
        handled = true;
    }
    return IntPtr.Zero;
  }
}
Yiao SUN
  • 908
  • 1
  • 8
  • 26
  • here are how to hide close button, when you want to close you can use `Alt + F4` -@Prohor – Yiao SUN Sep 01 '16 at 07:11
  • Thank you. But my application is Prism multimodule application. It means that it consisits of the main window and many views each of which is a UserControl located in a separate module. So I use the notification dialog not only in main window but also in the other views that are UserControls in the mudules. Is your approach sutable not only for Window but also for UserControl? – Prohor Sep 01 '16 at 10:56
  • It's only for window, i propose you to create an other windows just for this @Prohor Like you create a new window which name is window2 `window2 win2 = new window2(); win2.Show(); this.Close();`Those codes you wirite in your `window 1`with a event or whatelse, Like this you can open this window, in this window you just add what you need like what you did in your usercontrol – Yiao SUN Sep 01 '16 at 11:12
  • I opened an issue for voting in the WPF github repository to add more control over these buttons: https://github.com/dotnet/wpf/issues/4294 – Thraka Mar 18 '21 at 17:50
1

I have a workaround, if it suits your structure. Expose a Usercontrol loaded event in code behind (can be achieved also using MVVM) of your Usercontrol NotificationDialogPopupView

Loaded="UserControl_Loaded"

and write down following code in the Loaded event

private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            Window win = ((UserControl)sender).Parent as Window;
            if(win != null)
            {
                win.WindowStyle = WindowStyle.None;
                win.ResizeMode = ResizeMode.NoResize;

            }
        }
Manish Dubey
  • 706
  • 4
  • 17
0

I don't have any working example right now so I might have an uncomplete answer.

By looking to Prism source code PopupWindowAction I can see a WindowStyle property that you can use to change the style of the popup. I guess the property value you are looking for is WindowStyle="ToolWindow".

Hope it helps!

Amaury Levé
  • 1,459
  • 10
  • 21
  • It produces the following error "Typeconvertor class for style doesn't support conversion from string". – Prohor Aug 31 '16 at 13:14