Benutzer mit den meisten Antworten
Dialog-Typ gesucht

Frage
-
Hallo,
seit Windows 8 gibt es einen Dialog, der den gesamten Desktop leicht abdunkelt und eine Nachricht mit Buttons auf einem breiten Balken anzeigt, so z.B. auf Notebooks die Nachricht wenn der Akkustand gering ist. Ich habe den Dialog aber auch schon in anderem Zusammenhang gesehen, mit mehreren Buttons. Er erscheint unabhängig davon, ob man sich auf dem Desktop oder auf der Kachel-Oberfläche bzw. in einer FullScreen-App befindet.
Kann man diesen Dialog per Programm aufrufen und gestalten?
Hat er einen speziellen Namen?
Gruß
Heiko
Antworten
-
Hallo Heiko,
der von Windows verwendete Dialog sieht exakt so aus wie der MessageDialog der auch von den Apps genutzt wird. Das lässt mich vermuten dass da auch das selbe System dahinter steckt. Zugleich lassen sich egnau diese APIs aber auch nur aus den Apps heraus innerhalb des eigenen App-Rahmens aufrufen.
Wirklich Vollbild und Modal wird es also wahrscheinlich nicht werden. Auch wird das Verhalten unter Windows 10 sicherlich wieder geändert.
Ich fand auch noch den Beitrag Windows 8: TopMost vs. TopMost was die Absurdität des Fensterverhaltens wiederspiegelt. Darauf kam ich weil ich hofte dass ein TopMost-Fenster in den Vordergrund kommt. Dem war aber auch nicht so.
Was dagegen die Apps zumindest minimiert ist der Aufruf von SwitchToThisWindow (MSDN unedingt beachten!) oder SetForegroundWindow.
Der Dialog an sich verhält sich wie die UAC Dialoge, man bekommt sie eigentlich nicht weg und sie verhalten sich wie der Taskmanager in dem oben genannten Artikel. Ein 100%iges Nachbauen wird daher wahrscheinlich nicht möglich sein. Aber zumindest die Apps kann man damit minimieren und so das eigene Programm kurzzeitig in den Vordergrund bringen.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 22. Juni 2015 07:11
- Als Antwort markiert Heiko65456465 Dienstag, 30. Juni 2015 13:31
Alle Antworten
-
Hallo,
je nach dem welche Technologie du benutzt (WinForms, Win32...) kannst du so etwas auch selber gestalten.
Ferner ist z.B. das nicht ganz so; in Windows 10 ist das Ausshen stark verhändert worden aber es ist immer noch die selbe MessageBox.
© 2015 Thomas Roskop
Germany // Deutschland -
Hallo Thomas,
den Dialog nachzubauen, sodaß er optisch wie der gesuchte aussieht, wäre vermutlich kein Problem. Die Frage ist, wie ich ihn aufrufe, sodaß er nicht nur auf dem Desktop zu sehen ist, sondern auch auf der Kachel-Oberfläche während man sich dort in einer App befindet oder während durch die Kacheln blättert.
Ich habe zur Zeit ein normales Fenster, das bei Eintreten eines bestimmten Zustands aus dem TNA-Bereich (Task Notification Area) verschwindet und wieder eingeblendet wird. Wenn ich mich jedoch auf der Kachelöberfläche befinde, bekomme ich nicht mit, dass das Fenster auf dem Desktop geöffnet wurde. Deshalb suche ich nach einer Lösung, die wie das oben beschriebene funktioniert.
Gruß
Heiko -
Hallo Heiko,
der von Windows verwendete Dialog sieht exakt so aus wie der MessageDialog der auch von den Apps genutzt wird. Das lässt mich vermuten dass da auch das selbe System dahinter steckt. Zugleich lassen sich egnau diese APIs aber auch nur aus den Apps heraus innerhalb des eigenen App-Rahmens aufrufen.
Wirklich Vollbild und Modal wird es also wahrscheinlich nicht werden. Auch wird das Verhalten unter Windows 10 sicherlich wieder geändert.
Ich fand auch noch den Beitrag Windows 8: TopMost vs. TopMost was die Absurdität des Fensterverhaltens wiederspiegelt. Darauf kam ich weil ich hofte dass ein TopMost-Fenster in den Vordergrund kommt. Dem war aber auch nicht so.
Was dagegen die Apps zumindest minimiert ist der Aufruf von SwitchToThisWindow (MSDN unedingt beachten!) oder SetForegroundWindow.
Der Dialog an sich verhält sich wie die UAC Dialoge, man bekommt sie eigentlich nicht weg und sie verhalten sich wie der Taskmanager in dem oben genannten Artikel. Ein 100%iges Nachbauen wird daher wahrscheinlich nicht möglich sein. Aber zumindest die Apps kann man damit minimieren und so das eigene Programm kurzzeitig in den Vordergrund bringen.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 22. Juni 2015 07:11
- Als Antwort markiert Heiko65456465 Dienstag, 30. Juni 2015 13:31
-
Hallo Tom,
danke für deine Infos. Die TopMost-Sachen, inklusive SwitchToThisWindow() (ausprobiert), scheinen nur für den Desktop zu funktionieren, und über den TaskManager haben sich offenbar schon andere den Kopf zerbrochen.
Das mit den "Apps minimieren" habe ich noch nicht verstanden. SwitchToThisWindow() bringt bei mir auch nur die Anwendung (Windows Forms) in den Vordergrund, wenn ich auf dem Desktop bin.
Allerdings vermute ich, dass es spezielle Berechtigungen und Voraussetzungen verlangt, vor allem, weil es wie der MessageDialog aus der App-Entwicklung aussieht, und die Apps müssen Windows erst mal darum bitten, bestimmte Dinge ausführen zu können.
Ich hatte gehofft, es gäbe da etwas ganz zentrales und System-weites, was man einfach so benutzen könnte, ist offenbar etwas komplizierter. Ich geb' mich damit erst mal zufrieden.
Danke und Gruß
Heiko- Bearbeitet Heiko65456465 Freitag, 19. Juni 2015 16:53
-
Hallo Heiko,
Hat Toms Antwort Dir geholfen? Bist Du weitergekommen?
Gruß,
DimitarBitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.
-
Hallo Thomas,
also bei einer Windows Store App würde man den MessageDialog nutzen. Den gibt es aber leider bei WPF auf dem Desktop nicht.
Daher habe ich ein UserControl dafür gebaut:
<UserControl x:Class="ProductName.Client.Dashboard.View.MessageView" 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:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls" mc:Ignorable="d" d:DesignHeight="900" d:DesignWidth="1200" Background="Transparent" DataContext="{Binding MessageViewModel, Source={StaticResource Locator}}" Visibility="{Binding Path=IsOpen, Converter={StaticResource BoolToVisibilityConverter}}" Panel.ZIndex="99999"> <Grid x:Name="LayoutRoot"> <Grid.Background> <SolidColorBrush Color="DimGray" Opacity="0.7"/> </Grid.Background> <Grid Height="300"> <Grid.Background> <SolidColorBrush Opacity="1" Color="{Binding Path=BackColor}" /> </Grid.Background> <StackPanel VerticalAlignment="Center"> <TextBlock Text="{Binding Path=Caption}" Style="{StaticResource TextBlock_XXXLargeTextStyle}" TextWrapping="NoWrap" Margin="150,0,150,0" HorizontalAlignment="Left" VerticalAlignment="Center"> <TextBlock.Foreground> <SolidColorBrush Color="{Binding Path=ForeColor}" /> </TextBlock.Foreground> </TextBlock> <ScrollViewer Margin="150,20,150,40" MaxHeight="150" VerticalScrollBarVisibility="Auto"> <TextBlock Text="{Binding Path=Text}" Style="{StaticResource TextBlock_LargeTextStyle}" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center"> <TextBlock.Foreground> <SolidColorBrush Color="{Binding Path=ForeColor}" /> </TextBlock.Foreground> </TextBlock> </ScrollViewer> </StackPanel> <controls:MetroProgressBar Height="6" Margin="0,0,0,2" VerticalAlignment="Bottom" IsIndeterminate="True" Visibility="{Binding Path=IsProgressBarVisible, Converter={StaticResource BoolToVisibilityConverter}}" Foreground="{StaticResource AccentColorBrush}" /> <StackPanel Orientation="Horizontal" Margin="150,0,150,20" HorizontalAlignment="Center" VerticalAlignment="Bottom"> <Button Content="OK" Visibility="{Binding Path=IsOkButtonVisible, Converter={StaticResource BoolToVisibilityConverter}}" Height="26" Width="120" Margin="10,0,20,0" Command="{Binding OnOkClickCommand}" /> <Button Content="Ja" Visibility="{Binding Path=IsYesNoButtonVisible, Converter={StaticResource BoolToVisibilityConverter}}" Height="26" Width="120" Margin="10,0,20,0" Command="{Binding Path=OnYesClickCommand}"> </Button> <Button Content="Nein" Visibility="{Binding Path=IsYesNoButtonVisible, Converter={StaticResource BoolToVisibilityConverter}}" Height="26" Width="120" Margin="10,0,20,0"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <ei:ChangePropertyAction TargetObject="{Binding}" PropertyName="IsOpen" Value="False"/> </i:EventTrigger> </i:Interaction.Triggers> </Button> </StackPanel> </Grid> </Grid> </UserControl>
Codebehind gibt es keinen, da ich MVVM verwende und an ein ViewModel binde. Das ViewModel sieht so aus:
using System.Windows.Input; using System.Windows.Media; using ProductName.Client.Dashboard.Enums; using GalaSoft.MvvmLight.Command; namespace ProductName.Client.Dashboard.ViewModel { public class MessageViewModel : ViewModelBase { private string _caption; private string _text; private Color _backColor; bool _isOpen; private MessageViewButtonTypeEnum _messageViewButtonsType; private bool _isYesNoButtonVisible; private bool _isOkButtonVisible; private MessageViewTypeEnum _messageViewType; Color _foreColor; ICommand _yesClickCommand; ICommand _noClickCommand; ICommand _okClickCommand; public event OnYesButtonClickedEventHandler OnYesButtonClicked; public delegate void OnYesButtonClickedEventHandler(object data); public event OnNoButtonClickedEventHandler OnNoButtonClicked; public delegate void OnNoButtonClickedEventHandler(object data); public event OnOkButtonClickedEventHandler OnOkButtonClicked; public delegate void OnOkButtonClickedEventHandler(object data); public MessageViewModel() { if (IsInDesignMode) { MessageViewButtons = MessageViewButtonTypeEnum.YesNo; MessageViewType = MessageViewTypeEnum.Info; Caption = "Überschrift"; Text = "bla bla bla bla bla"; IsOpen = true; } } public void Close() { IsOpen = false; } public void Open() { IsOpen = true; } public MessageViewTypeEnum MessageViewType { get { return _messageViewType; } set { _messageViewType = value; OnPropertyChanged(); SetMessageViewType(); } } /// <summary> /// Just an additional dataobject to pass to the ViewModel. /// It can be used to distinguish ViewModel usages. /// </summary> /// <value></value> /// <returns></returns> /// <remarks></remarks> public object DataObject { get; set; } private void SetMessageViewType() { switch (MessageViewType) { case MessageViewTypeEnum.Error: BackColor = Colors.Red; ForeColor = Colors.White; break; case MessageViewTypeEnum.Info: BackColor = Colors.White; ForeColor = Colors.Black; break; case MessageViewTypeEnum.Warning: BackColor = Colors.Wheat; ForeColor = Colors.Black; break; } } public MessageViewButtonTypeEnum MessageViewButtons { get { return _messageViewButtonsType; } set { _messageViewButtonsType = value; OnPropertyChanged(); SetMessageViewButtons(); } } public bool IsYesNoButtonVisible { get { return _isYesNoButtonVisible; } set { _isYesNoButtonVisible = value; OnPropertyChanged(); } } private void SetMessageViewButtons() { switch (MessageViewButtons) { case MessageViewButtonTypeEnum.Ok: IsYesNoButtonVisible = false; IsOkButtonVisible = true; break; case MessageViewButtonTypeEnum.YesNo: IsYesNoButtonVisible = true; IsOkButtonVisible = false; break; default: IsYesNoButtonVisible = false; IsOkButtonVisible = false; break; } } public bool IsOkButtonVisible { get { return _isOkButtonVisible; } set { _isOkButtonVisible = value; OnPropertyChanged(); } } public string Caption { get { return _caption; } set { _caption = value; OnPropertyChanged(); } } public string Text { get { return _text; } set { _text = value; OnPropertyChanged(); } } public Color BackColor { get { return _backColor; } set { _backColor = value; OnPropertyChanged(); } } public bool IsOpen { get { return _isOpen; } set { _isOpen = value; OnPropertyChanged(); } } public Color ForeColor { get { return _foreColor; } set { _foreColor = value; OnPropertyChanged(); } } public ICommand OnYesClickCommand { get { if ((_yesClickCommand == null)) { _yesClickCommand = new RelayCommand(OnYesClickCommandExecute); } return _yesClickCommand; } } private void OnYesClickCommandExecute() { if (OnYesButtonClicked != null) { OnYesButtonClicked(DataObject); } } public ICommand OnNoClickCommand { get { if ((_noClickCommand == null)) { _noClickCommand = new RelayCommand(OnNoClickCommandExecute); } return _noClickCommand; } } private void OnNoClickCommandExecute() { if (OnNoButtonClicked != null) { OnNoButtonClicked(DataObject); } } public ICommand OnOkClickCommand { get { if ((_okClickCommand == null)) { _okClickCommand = new RelayCommand(OnOkClickCommandExecute); } return _okClickCommand; } } private void OnOkClickCommandExecute() { if (OnOkButtonClicked != null) { OnOkButtonClicked(DataObject); } } } }
Ich binde das UserControl einfach an der letzten Stelle im LayoutRoot in die View ein:
<view1:MessageView d:IsHidden="True" />
Über den DataContext und Binding wird dieses UserControl einfach auf Visible=true gestellt, sodass es sichtbar wird. Da es an der letzten Stelle (ganz unten) im XAML steht, wird es im UI auf der ZOrder ganz oben angezeigt. Über die ICommands kann man sich an die Click-Events der Buttons OK, Yes, No anhängen und entsprechend darauf reagieren.
Beispiel aus dem WPF Designer:
Übrigens verwende ich MVVM mit DataContext über den ViewModelLocator von GalaSoft.MvvmLight.
Viel Erfolg
- Bearbeitet shaper Dienstag, 30. Juni 2015 20:32