Omówienie okien WPF (WPF .NET)
Użytkownicy korzystają z aplikacji Windows Presentation Foundation (WPF) za pośrednictwem okien. Głównym celem okna jest hostowanie zawartości, która wizualizuje dane i umożliwia użytkownikom interakcję z danymi. Aplikacje WPF udostępniają własne okna przy użyciu klasy Window. W tym artykule przedstawiono klasę Window przed omówieniem podstaw tworzenia okien i zarządzania nimi w aplikacjach.
Ważne
W tym artykule jest używany kod XAML wygenerowany na podstawie projektu języka C#. Jeśli używasz języka Visual Basic, kod XAML może wyglądać nieco inaczej. Te różnice zwykle występują w wartościach atrybutu x:Class
. Język C# uwzględnia przestrzeń nazw katalogu głównego projektu, a język Visual Basic nie.
Szablony projektów dla języka C# tworzą typ App
zawarty w pliku app.xaml. W języku Visual Basic ten typ ma nazwę Application
, a plik ma nazwę Application.xaml
.
Klasa Window
W programie WPF okno jest hermetyzowane przez klasę Window używaną do wykonywania następujących czynności:
- Wyświetlanie okna.
- Konfigurowanie rozmiaru, położenia i wyglądu okna.
- Hostowanie zawartości specyficznej dla aplikacji.
- Zarządzanie okresem istnienia okna.
Na poniższej ilustracji przedstawiono części składowe okna:
Okno jest podzielone na dwa obszary: obszar niekliencki i obszar klienta.
Obszar niekliencki okna jest implementowany przez platformę WPF i obejmuje części okna, które są wspólne dla większości okien, w tym następujące elementy:
- Pasek tytułu (1–5).
- Ikona (1).
- Tytuł (2).
- Przyciski Minimalizuj (3), Maksymalizuj (4) i Zamknij (5).
- Menu systemowe (6) z elementami menu. Pojawia się po kliknięciu ikony (1).
- Obramowanie (7).
Obszar klienta okna to obszar w obrębie obszaru nieklienckiego okna i jest używany przez deweloperów do dodawania zawartości specyficznej dla aplikacji, takiej jak paski menu, paski narzędzi i kontrolki.
- Obszar klienta (8).
- Uchwyt zmieniania rozmiaru (9). Jest to kontrolka dodawana do obszaru klienta (8).
Implementowanie okna
Implementacja typowego okna obejmuje zarówno wygląd, jak i zachowanie, przy czym wygląd definiuje wygląd okna widoczny dla użytkowników, a zachowanie definiuje sposób działania okna, gdy użytkownicy z niego korzystają. Na platformie WPF można zaimplementować wygląd i zachowanie okna przy użyciu kodu lub znaczników XAML.
Jednak na ogół wygląd okna jest implementowany przy użyciu znaczników XAML, a jego zachowanie jest implementowane przy użyciu pliku codebehind, jak pokazano w poniższym przykładzie.
<Window x:Class="WindowsOverview.Window1"
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:local="clr-namespace:WindowsOverview"
>
<!-- Client area containing the content of the window -->
</Window>
Poniższy kod to plik codebehind dla języka XAML.
using System.Windows;
namespace WindowsOverview
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
}
}
Public Class Window1
End Class
Aby umożliwić współdziałanie pliku znaczników XAML i pliku związanego z kodem, wymagane są następujące elementy:
W znacznikach element
Window
musi zawierać atrybutx:Class
. Gdy aplikacja zostanie skompilowana, istnienie atrybutux:Class
spowoduje, że aparat kompilacji firmy Microsoft (MSBuild) wygeneruje klasępartial
pochodzącą z klasy Window o nazwie określonej przez atrybutx:Class
. Wymaga to dodania deklaracji przestrzeni nazw XML dla schematu XAML (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
). Wygenerowana klasapartial
implementuje metodęInitializeComponent
, która jest wywoływana w celu zarejestrowania zdarzeń i ustawienia właściwości implementowanych w znacznikach.W pliku codebehind klasa musi być klasą
partial
o tej samej nazwie, która jest określona przez atrybutx:Class
w znacznikach, i musi pochodzić z klasy Window. Umożliwia to skojarzenie pliku związanego z kodem z klasąpartial
, która jest generowana dla pliku znaczników podczas kompilowania aplikacji. Aby uzyskać więcej informacji, zobacz Kompilowanie aplikacji WPF.W pliku codebehind klasa Window musi zaimplementować konstruktora, który wywołuje metodę
InitializeComponent
. MetodaInitializeComponent
jest implementowana przez wygenerowaną klasępartial
pliku znaczników w celu rejestrowania zdarzeń i ustawiania właściwości zdefiniowanych w znacznikach.
Uwaga
Po dodaniu nowej klasy Window do projektu przy użyciu programu Visual Studio klasa Window jest implementowana przy użyciu zarówno znaczników, jak i pliku codebehind, oraz zawiera niezbędną konfigurację do utworzenia skojarzenia między znacznikami i plikami związanymi z kodem zgodnie z opisem w tym miejscu.
Dzięki tej konfiguracji można skupić się na zdefiniowaniu wyglądu okna w znacznikach XAML i zaimplementowaniu jego zachowania w pliku codebehind. Poniższy przykład przedstawia okno z przyciskiem definiującym obsługę zdarzeń dla zdarzenia Click. Jest to implementowane w języku XAML, a procedura obsługi jest implementowana w pliku codebehind.
<Window x:Class="WindowsOverview.Window1"
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:local="clr-namespace:WindowsOverview"
>
<!-- Client area containing the content of the window -->
<Button Click="Button_Click">Click This Button</Button>
</Window>
Poniższy kod to plik codebehind dla języka XAML.
using System.Windows;
namespace WindowsOverview
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button was clicked.");
}
}
}
Public Class Window1
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
MessageBox.Show("Button was clicked.")
End Sub
End Class
Konfigurowanie okna dla programu MSBuild
Sposób implementacji okna określa, jak jest ono skonfigurowane dla programu MSBuild. W przypadku okna zdefiniowanego przy użyciu znaczników XAML i pliku codebehind:
- Pliki znaczników XAML są konfigurowane jako elementy
Page
programu MSBuild. - Pliki związane z kodem są konfigurowane jako elementy
Compile
programu MSBuild.
Projekty zestawu SDK platformy .NET automatycznie importują poprawne elementy Page
i Compile
nie trzeba ich deklarować. Po skonfigurowaniu projektu dla platformy WPF pliki znaczników XAML są automatycznie importowane jako elementy Page
, a odpowiedni plik związany z kodem jest importowany jako element Compile
.
Projekty programu MSBuild nie będą automatycznie importować typów i należy je zadeklarować samodzielnie:
<Project>
...
<Page Include="MarkupAndCodeBehindWindow.xaml" />
<Compile Include=" MarkupAndCodeBehindWindow.xaml.cs" />
...
</Project>
Aby uzyskać informacje na temat tworzenia aplikacji WPF, zobacz Kompilowanie aplikacji WPF.
Okres istnienia okna
Podobnie jak w przypadku każdej klasy okno ma okres istnienia, który rozpoczyna się, gdy po raz pierwszy zostanie utworzone jego wystąpienie, po czym jest ono otwierane, uaktywniane/dezaktywowane i ostatecznie zamykane.
Otwieranie okna
Aby otworzyć okno, należy najpierw utworzyć jego wystąpienie, co zostało pokazane w poniższym przykładzie:
using System.Windows;
namespace WindowsOverview
{
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
// Create the window
Window1 window = new Window1();
// Open the window
window.Show();
}
}
}
Class Application
Private Sub Application_Startup(sender As Object, e As StartupEventArgs)
' Create the window
Dim window As New Window1
' Open the window
window.Show()
End Sub
End Class
W tym przykładzie dla klasy Window1
jest tworzone wystąpienie po uruchomieniu aplikacji, co następuje po wywołaniu zdarzenia Startup. Aby uzyskać więcej informacji na temat okna uruchamiania, zobacz Jak pobrać lub ustawić główne okno aplikacji.
Po utworzeniu wystąpienia okna odwołanie do niego jest automatycznie dodawane do listy okien zarządzanej przez obiekt Application. Pierwsze okno do utworzenia wystąpienia jest automatycznie ustawiane przez klasę Application jako główne okno aplikacji.
Okno jest ostatecznie otwierane przez wywołanie metody Show, jak pokazano na poniższej ilustracji:
Okno otwarte przez wywołanie metody Show to okno niemodalne, a aplikacja nie uniemożliwia użytkownikom interakcji z innymi oknami w aplikacji. Otwarcie okna przy użyciu metody ShowDialog powoduje otwarcie okna jako modalnego i ogranicza interakcję użytkownika do konkretnego okna. Aby uzyskać więcej informacji, zobacz Omówienie okien dialogowych.
Po wywołaniu metody Show okno wykonuje inicjowanie zanim zostanie wyświetlone, aby ustanowić infrastrukturę, która umożliwia mu odbieranie danych wejściowych użytkownika. Po zainicjowaniu okna zostanie wywołane zdarzenie SourceInitialized i zostanie wyświetlone okno.
Aby uzyskać więcej informacji, zobacz Jak otworzyć okno lub okno dialogowe.
Okno uruchamiania
W poprzednim przykładzie użyto zdarzenia Startup
do uruchomienia kodu, który powodował wyświetlenie początkowego okna aplikacji. Zamiast tego, w ramach skrótu, użyj interfejsu StartupUri, aby określić ścieżkę do pliku XAML w aplikacji. Aplikacja automatycznie tworzy i wyświetla okno określone przez tę właściwość.
<Application x:Class="WindowsOverview.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WindowsOverview"
StartupUri="ClippedWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
Własność okna
Okno otwierane przy użyciu metody Show nie ma niejawnej relacji z oknem, które je utworzyło. Użytkownicy mogą korzystać z obu okien niezależnie od siebie, co oznacza, że każde z okien może wykonywać następujące operacje:
- Zakrywanie drugiego (chyba że jedno z okien ma dla właściwości Topmost ustawioną wartość
true
). - Być minimalizowane, maksymalizowane i przywracane bez wywierania wpływu na drugie.
Niektóre okna wymagają relacji z oknem, które je otwiera. Na przykład aplikacja zintegrowanego środowiska projektowego (IDE) może otwierać okna właściwości i okna narzędzi, a ich typowym zachowaniem jest zakrywanie okna, które je utworzyło. Ponadto takie okna powinny zawsze być zamykane, minimalizowane, maksymalizowane i przywracane w połączeniu z oknem, które je utworzyło. Taką relację można ustanowić, przez uczynienie jednego okna właścicielem innego okna. Osiągane jest to przez ustawienie właściwości Owner okna posiadanego z odwołaniem do okna będącego właścicielem. Jest to pokazane w następującym przykładzie.
private void Button_Click(object sender, RoutedEventArgs e)
{
// Create a window and make the current window its owner
var ownedWindow = new ChildWindow1();
ownedWindow.Owner = this;
ownedWindow.Show();
}
Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
' Create a window and make the current window its owner
Dim ownedWindow As New ChildWindow1
ownedWindow.Owner = Me
ownedWindow.Show()
End Sub
Po ustanowieniu własności:
- Okno posiadane może odwoływać się do okna będącego jego właścicielem przez sprawdzenie wartości jego właściwości Owner.
- Okno będące właścicielem może odnajdować wszystkie okna, których jest właścicielem, przez sprawdzenie wartości jego właściwości OwnedWindows.
Aktywacja okna
Po otwarciu okna po raz pierwszy staje się ono oknem aktywnym. Okno aktywne to okno, które obecnie przechwytuje dane wejściowe użytkownika, takie jak naciśnięcia klawiszy i kliknięcia myszy. Gdy okno stanie się aktywne, wywołuje zdarzenie Activated.
Uwaga
Po pierwszym otwarciu okna zdarzenia Loaded i ContentRendered są wywoływane dopiero po wywołaniu zdarzenia Activated. Mając to na uwadze, okno może być uznawane za otwarte, gdy zostanie wywołane zdarzenie ContentRendered.
Gdy okno stanie się aktywne, użytkownik może aktywować inne okno w tej samej aplikacji lub aktywować inną aplikację. W takim przypadku obecnie aktywne okno zostanie zdezaktywowane i wywoła zdarzenie Deactivated. Podobnie, gdy użytkownik wybierze obecnie dezaktywowane okno, okno stanie się ponownie aktywne i zostanie wywołane zdarzenie Activated.
Jednym z typowych powodów obsługi zdarzeń Activated i Deactivated jest włączenie i wyłączenie funkcji, która może być uruchamiana tylko wtedy, gdy okno jest aktywne. Na przykład niektóre okna wyświetlają interaktywną zawartość, która wymaga stałego wprowadzania danych przez użytkownika lub jego uwagi, takie jak gry i odtwarzacze wideo. Poniższy przykład to uproszczony odtwarzacz wideo, który pokazuje, jak obsługiwać zdarzenia Activated i Deactivated w celu zaimplementowania tego zachowania.
<Window x:Class="WindowsOverview.CustomMediaPlayerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Activated="Window_Activated"
Deactivated="Window_Deactivated"
Title="CustomMediaPlayerWindow" Height="450" Width="800">
<Grid>
<MediaElement x:Name="mediaElement" Stretch="Fill"
LoadedBehavior="Manual" Source="numbers.mp4" />
</Grid>
</Window>
Poniższy kod to plik codebehind dla języka XAML.
using System;
using System.Windows;
namespace WindowsOverview
{
public partial class CustomMediaPlayerWindow : Window
{
public CustomMediaPlayerWindow() =>
InitializeComponent();
private void Window_Activated(object sender, EventArgs e)
{
// Continue playing media if window is activated
mediaElement.Play();
}
private void Window_Deactivated(object sender, EventArgs e)
{
// Pause playing if media is being played and window is deactivated
mediaElement.Pause();
}
}
}
Public Class CustomMediaPlayerWindow
Private Sub Window_Activated(sender As Object, e As EventArgs)
' Continue playing media if window Is activated
mediaElement.Play()
End Sub
Private Sub Window_Deactivated(sender As Object, e As EventArgs)
' Pause playing if media is being played and window is deactivated
mediaElement.Pause()
End Sub
End Class
Inne typy aplikacji mogą nadal uruchamiać kod w tle po dezaktywacji okna. Na przykład klient poczty może kontynuować sondowanie serwera poczty, gdy użytkownik korzysta z innych aplikacji. Aplikacje takie jak te często udostępniają inne lub dodatkowe zachowanie, gdy okno główne jest dezaktywowane. W przypadku programu poczty może to oznaczać zarówno dodanie nowego elementu poczty do skrzynki odbiorczej, jak i dodanie ikony powiadomienia do zasobnika systemu. Ikona powiadomienia musi być wyświetlana tylko wtedy, gdy okno poczty nie jest aktywne, co jest ustalane przez sprawdzenie właściwości IsActive.
Jeśli zadanie w tle zakończy się, okno może wysłać do użytkownika bardziej pilne powiadomienie przez wywołanie metody Activate. Jeśli użytkownik wchodzi w interakcję z inną aplikacją uaktywnioną po wywołaniu zdarzenia Activate, przycisk paska zadań okna miga. Jeśli jednak użytkownik wchodzi w interakcję z bieżącą aplikacją, wywołanie zdarzenia Activate spowoduje przełączenie okna na pierwszy plan.
Uwaga
Aktywację w zakresie aplikacji można obsługiwać przy użyciu zdarzeń Application.Activated i Application.Deactivated.
Zapobieganie aktywacji okna
Istnieją scenariusze, w których okna nie powinny być uaktywniane po ich wyświetleniu, takie jak okna konwersacji aplikacji czatu lub okna powiadomień aplikacji poczty e-mail.
Jeśli aplikacja ma okno, które nie powinno być uaktywniane po jego wyświetleniu, można ustawić dla jej właściwości ShowActivated wartość false
przed wywołaniem metody Show po raz pierwszy. W konsekwencji:
- Okno nie jest uaktywnione.
- Zdarzenie okna Activated nie jest wywoływane.
- Obecnie uaktywnione okno pozostaje uaktywnione.
Okno zostanie uaktywnione, jednak dopiero gdy uaktywni je użytkownik przez kliknięcie obszaru klienta lub nieklienckiego. W takim przypadku:
- Okno jest uaktywnione.
- Zdarzenie okna Activated jest wywoływane.
- Okno uaktywnione wcześniej jest dezaktywowane.
- Zdarzenia Deactivated i Activated okna są następnie wywoływane zgodnie z oczekiwaniami w reakcji na akcje użytkownika.
Zamykanie okna
Okres życia okna zaczyna zbliżać się do końca po zamknięciu go przez użytkownika. Po zamknięciu okna nie można go ponownie otworzyć. Okno można zamknąć przy użyciu elementów w obszarze nieklienckim, takich jak poniższe:
- Element Zamknij menu System.
- Naciśnięcie klawiszy ALT + F4.
- Naciśnięcie przycisku Zamknij.
- Naciśnięcie klawisza ESC, gdy przycisk ma dla właściwości IsCancel ustawioną wartość
true
w oknie modalnym.
Możesz udostępnić więcej mechanizmów zamykania okna w obszarze klienta, z których najczęstsze są następujące:
- Element Zakończ w menu Plik, zwykle w przypadku głównych okien aplikacji.
- Element Zamknij w menu Plik, zwykle w pomocniczym oknie aplikacji.
- Przycisk Anuluj, zwykle w modalnym oknie dialogowym.
- Przycisk Zamknij, zwykle w niemodalnym oknie dialogowym.
Aby zamknąć okno w reakcji na jeden z tych mechanizmów niestandardowych, należy wywołać metodę Close. Poniższy przykład implementuje możliwość zamknięcia okna przez wybranie polecenia Zakończ z menu Plik.
<Window x:Class="WindowsOverview.ClosingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ClosingWindow" Height="450" Width="800">
<StackPanel>
<Menu>
<MenuItem Header="_File">
<MenuItem Header="E_xit" Click="fileExitMenuItem_Click" />
</MenuItem>
</Menu>
</StackPanel>
</Window>
Poniższy kod to plik codebehind dla języka XAML.
using System.Windows;
namespace WindowsOverview
{
public partial class ClosingWindow : Window
{
public ClosingWindow() =>
InitializeComponent();
private void fileExitMenuItem_Click(object sender, RoutedEventArgs e)
{
// Close the current window
this.Close();
}
}
}
Public Class ClosingWindow
Private Sub fileExitMenuItem_Click(sender As Object, e As RoutedEventArgs)
' Close the current window
Me.Close()
End Sub
End Class
Uwaga
Aplikację można skonfigurować tak, aby była automatycznie zamykana po zamknięciu głównego okna aplikacji (zobacz MainWindow) lub zamknięciu ostatniego okna. Aby uzyskać więcej informacji, zobacz ShutdownMode.
Chociaż okno można jawnie zamknąć za pomocą mechanizmów udostępnianych w obszarach klienta i nieklienckich, okno może również zostać niejawnie zamknięte w wyniku zachowania w innych częściach aplikacji lub systemu Windows, w tym następujących:
- Użytkownik wylogował się lub zamknął system Windows.
- Zamknięto element Owner okna.
- Zamknięto główne okno aplikacji i atrybut ShutdownMode ma wartość OnMainWindowClose.
- Wywołano metodę Shutdown.
Ważne
Nie można ponownie otworzyć okna po jego zamknięciu.
Anulowanie zamknięcia okna
Gdy okno zostanie zamknięte, wywołuje dwa zdarzenia: Closing i Closed.
Zdarzenie Closing jest wywoływane przed zamknięciem okna i zapewnia mechanizm, za pomocą którego można zapobiec zamknięciu okna. Jedną z typowych przyczyn zapobiegania zamykaniu okna jest to, że zawartość okna zawiera zmodyfikowane dane. W takiej sytuacji można obsłużyć zdarzenie Closing w celu ustalenia, czy dane są zanieczyszczone, a jeśli tak, do zapytania użytkownika, czy kontynuować zamykanie okna bez zapisywania danych, czy anulować zamknięcie okna. W poniższym przykładzie przedstawiono kluczowe aspekty obsługi zdarzenia Closing.
<Window x:Class="WindowsOverview.DataWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataWindow" Height="450" Width="800"
Closing="Window_Closing">
<Grid>
<TextBox x:Name="documentTextBox" TextChanged="documentTextBox_TextChanged" />
</Grid>
</Window>
Poniższy kod to plik codebehind dla języka XAML.
using System.Windows;
using System.Windows.Controls;
namespace WindowsOverview
{
public partial class DataWindow : Window
{
private bool _isDataDirty;
public DataWindow() =>
InitializeComponent();
private void documentTextBox_TextChanged(object sender, TextChangedEventArgs e) =>
_isDataDirty = true;
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// If data is dirty, prompt user and ask for a response
if (_isDataDirty)
{
var result = MessageBox.Show("Document has changed. Close without saving?",
"Question",
MessageBoxButton.YesNo);
// User doesn't want to close, cancel closure
if (result == MessageBoxResult.No)
e.Cancel = true;
}
}
}
}
Public Class DataWindow
Private _isDataDirty As Boolean
Private Sub documentTextBox_TextChanged(sender As Object, e As TextChangedEventArgs)
_isDataDirty = True
End Sub
Private Sub Window_Closing(sender As Object, e As ComponentModel.CancelEventArgs)
' If data is dirty, prompt user and ask for a response
If _isDataDirty Then
Dim result = MessageBox.Show("Document has changed. Close without saving?",
"Question",
MessageBoxButton.YesNo)
' User doesn't want to close, cancel closure
If result = MessageBoxResult.No Then
e.Cancel = True
End If
End If
End Sub
End Class
Do obsługi zdarzeń Closing jest przekazywany element CancelEventArgs implementujący właściwość Cancel, dla której ustawiono wartość true
, aby zapobiegać zamknięciu okna.
Jeśli zdarzenie Closing nie jest obsługiwane lub jest obsługiwane, ale nie zostało anulowane, okno zostanie zamknięte. Tuż przed zamknięciem okna zostanie wywołane zdarzenie Closed. W tym momencie nie można uniemożliwić zamknięcia okna.
Zdarzenia okresu istnienia okna
Poniższa ilustracja przedstawia sekwencję głównych zdarzeń w okresie istnienia okna:
Poniższa ilustracja przedstawia sekwencję głównych zdarzeń w okresie istnienia okna, które jest wyświetlane bez aktywacji (dla właściwości ShowActivated ustawiono wartość false
przed wyświetleniem okna):
Lokalizacja okna
Gdy okno jest otwarte, ma lokalizację w wymiarach X i Y względem pulpitu. Tę lokalizację można ustalić, sprawdzając odpowiednio właściwości Left i Top. Ustaw te właściwości, aby zmienić lokalizację okna.
Możesz również określić początkową lokalizację obiektu Window po jego wyświetleniu po raz pierwszy, ustawiając dla właściwości WindowStartupLocation jedną z następujących wartości wyliczenia WindowStartupLocation:
- CenterOwner (domyślne)
- CenterScreen
- Manual
Jeśli lokalizacja uruchamiania jest określona jako Manual, a właściwości Left i Top nie zostały ustawione, obiekt Window zapyta system operacyjny o lokalizację, w której ma zostać wyświetlony.
Okna najwyżej w hierarchii i porządek osi Z
Oprócz lokalizacji w wymiarach X i Y okno ma również lokalizację w wymiarze Z, który określa jego położenie pionowe w odniesieniu do innych okien. Jest to nazywane porządkiem osi Z okna i istnieją jego dwa typy: normalny i najwyżej w hierarchii. Lokalizacja okna w normalnym porządku osi Z zależy od tego, czy jest ono obecnie aktywne, czy nie. Domyślnie okno znajduje się w normalnym porządku osi Z. Lokalizacja okna w najwyższym w hierarchii porządku osi Z także zależy od tego, czy jest ono obecnie aktywne, czy nie. Ponadto okna w najwyższym w hierarchii porządku osi Z są zawsze umieszczone nad oknami w normalnym porządku wzdłuż osi Z. Okno jest umieszczane w najwyższym w hierarchii porządku osi Z po ustawieniu dla jego właściwości Topmost wartości true
.
W każdym typie hierarchii porządku osi Z obecnie aktywne okno jest wyświetlane powyżej wszystkich innych okien w tym samym porządku osi Z.
Rozmiar okna
Oprócz lokalizacji na pulpicie okno ma rozmiar, który jest określany przez kilka właściwości, w tym różne właściwości szerokości i wysokości oraz SizeToContent.
Właściwości MinWidth, Width i MaxWidth są używane do zarządzania zakresem szerokości, które okno może mieć w swoim okresie istnienia.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
MinWidth="300" Width="400" MaxWidth="500">
</Window>
Wysokość okna jest zarządzana przez właściwości MinHeight, Height i MaxHeight.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
MinHeight="300" Height="400" MaxHeight="500">
</Window>
Ponieważ różne wartości szerokości i wysokości określają zakres, można określić szerokość i wysokość okna z możliwością zmiany rozmiaru w dowolnym miejscu w określonym zakresie dla odpowiedniego wymiaru. Aby wykryć bieżącą szerokość i wysokość, sprawdź odpowiednio właściwości ActualWidth i ActualHeight.
Jeśli chcesz, aby szerokość i wysokość okna miały rozmiar pasujący do rozmiaru zawartości okna, możesz użyć właściwości SizeToContent, która ma następujące wartości:
- SizeToContent.Manual
Brak efektu (wartość domyślna). - SizeToContent.Width
Dopasuj do szerokości zawartości, co ma taki sam efekt jak ustawienie zarówno właściwości MinWidth, jak i MaxWidth na szerokość zawartości. - SizeToContent.Height
Dopasuj do wysokości zawartości, co ma taki sam efekt jak ustawienie zarówno właściwości MinHeight, jak i MaxHeight na wysokość zawartości. - SizeToContent.WidthAndHeight
Dopasuj do szerokości i wysokości zawartości, co ma taki sam efekt jak ustawienie zarówno właściwości MinHeight, jak i MaxHeight na wysokość zawartości, oraz ustawienie zarówno właściwości MinWidth, jak i MaxWidth na szerokość zawartości.
W poniższym przykładzie pokazano okno, które automatycznie dopasowuje rozmiar do zawartości, zarówno w pionie, jak i w poziomie, gdy jest wyświetlane po raz pierwszy.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
SizeToContent="WidthAndHeight">
</Window>
W poniższym przykładzie pokazano, jak ustawić właściwość SizeToContent w kodzie, aby określić sposób zmieniania rozmiaru okna w celu dopasowania go do jego zawartości.
// Manually alter window height and width
this.SizeToContent = SizeToContent.Manual;
// Automatically resize width relative to content
this.SizeToContent = SizeToContent.Width;
// Automatically resize height relative to content
this.SizeToContent = SizeToContent.Height;
// Automatically resize height and width relative to content
this.SizeToContent = SizeToContent.WidthAndHeight;
' Manually alter window height and width
Me.SizeToContent = SizeToContent.Manual
' Automatically resize width relative to content
Me.SizeToContent = SizeToContent.Width
' Automatically resize height relative to content
Me.SizeToContent = SizeToContent.Height
' Automatically resize height and width relative to content
Me.SizeToContent = SizeToContent.WidthAndHeight
Kolejność pierwszeństwa dla właściwości określania rozmiaru
Zasadniczo różne właściwości rozmiarów okna łączą się w celu zdefiniowania zakresu szerokości i wysokości dla okna, którego rozmiar można zmieniać. Aby zapewnić utrzymanie prawidłowego zakresu, obiekt Window oblicza wartości właściwości rozmiaru przy użyciu następujących kolejności pierwszeństwa.
W przypadku właściwości wysokości:
- FrameworkElement.MinHeight
- FrameworkElement.MaxHeight
- SizeToContent.Height / SizeToContent.WidthAndHeight
- FrameworkElement.Height
W przypadku właściwości szerokości:
- FrameworkElement.MinWidth
- FrameworkElement.MaxWidth
- SizeToContent.Width / SizeToContent.WidthAndHeight
- FrameworkElement.Width
Kolejność pierwszeństwa może również określać rozmiar okna, gdy jest ono zmaksymalizowane. Do zarządzania tym służy właściwość WindowState.
Window state
W okresie istnienia okno z możliwością zmiany rozmiaru może mieć trzy stany: normalne, zminimalizowane i zmaksymalizowane. Okno w stanie normalnym to domyślny stan okna. Okno o tym stanie umożliwia użytkownikowi przenoszenie i zmienianie jego rozmiaru za pomocą uchwytu zmiany rozmiaru lub obramowania, jeśli zmiana rozmiaru jest możliwa.
Okno w stanie zminimalizowanym jest zwijane do przycisku paska zadań, jeśli dla właściwości ShowInTaskbar ustawiono wartość true
. W przeciwnym razie jest zwijane do najmniejszego możliwego rozmiaru, a następnie przenoszone do lewego dolnego rogu pulpitu. Nie można zmienić rozmiaru okna zminimalizowanego przy użyciu obramowania ani uchwytu zmiany rozmiaru, chociaż zminimalizowane okno, które nie jest wyświetlane na pasku zadań, można przeciągać po pulpicie.
Okno w stanie zmaksymalizowanym jest rozszerzone do maksymalnego rozmiaru, jaki może przyjąć, czyli będzie mieć maksymalnie takie rozmiary, na które zezwalają jego właściwości MaxWidth, MaxHeight i SizeToContent. Podobnie jak w przypadku okna zminimalizowanego, nie można zmieniać rozmiaru okna zmaksymalizowanego przy użyciu uchwytu zmiany rozmiaru ani przez przeciąganie obramowania.
Uwaga
Wartości właściwości Top, Left, Width i Height okna zawsze reprezentują wartości stanu normalnego, nawet jeśli okno jest obecnie zmaksymalizowane lub zminimalizowane.
Stan okna można skonfigurować, ustawiając jego właściwość WindowState, która może mieć jedną z następujących wartości wyliczenia WindowState:
W poniższym przykładzie pokazano, jak utworzyć okno, które po otwarciu jest wyświetlane jako zmaksymalizowane.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowState="Maximized">
</Window>
Na ogół należy ustawić właściwość WindowState w celu skonfigurowania początkowego stanu okna. Gdy zostanie wyświetlone okno z możliwością zmiany rozmiaru, użytkownicy mogą naciskać przyciski minimalizuj, maksymalizuj i przywróć na pasku tytułu okna, aby zmienić stan okna.
Wygląd okna
Wygląd obszaru klienta okna można zmienić, dodając do niego zawartość specyficzną dla okna, taką jak przyciski, etykiety i pola tekstowe. W celu skonfigurowania obszaru nieklienckiego klasa Window udostępnia kilka właściwości, które obejmują Icon do ustawiania ikony okna i Title do ustawiania jego tytułu.
Możesz również zmienić wygląd i zachowanie obramowania obszaru nieklienckiego, konfigurując tryb zmiany rozmiaru okna, styl okna i to, czy jest ono wyświetlane jako przycisk na pasku zadań pulpitu.
Tryb zmiany rozmiaru
W zależności od właściwości WindowStyle możesz kontrolować, czy i jak użytkownicy mogą zmieniać rozmiar okna. Styl okna wpływa na następujące aspekty:
- Zezwalanie na zmianę rozmiaru lub nie zezwalanie na nią przez przeciąganie obramowania okna myszą.
- Czy przyciski Minimalizuj, Maksymalizuj i Zamknij są wyświetlane w obszarze nieklienckim.
- Czy są włączone przyciski Minimalizuj, Maksymalizuj i Zamknij.
Możesz skonfigurować sposób zmieniania rozmiaru okna, ustawiając jego właściwość ResizeMode, która może być jedną z następujących wartości wyliczenia ResizeMode:
- NoResize
- CanMinimize
- CanResize (domyślne)
- CanResizeWithGrip
Podobnie jak w przypadku elementu WindowStylemało prawdopodobna jest modyfikacja trybu zmiany rozmiaru okna w okresie jego istnienia, co oznacza, że najprawdopodobniej będzie on ustawiany na podstawie znaczników XAML.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
ResizeMode="CanResizeWithGrip">
</Window>
Pamiętaj, że możesz wykryć, czy okno jest zmaksymalizowane, zminimalizowane lub przywrócone, sprawdzając właściwość WindowState.
Window style
Obramowanie uwidocznione z obszaru nieklienckiego okna jest odpowiednie dla większości aplikacji. Istnieją jednak okoliczności, w których potrzebne są różne typy obramowań lub w ogóle nie są potrzebne żadne obramowania, w zależności od typu okna.
Aby kontrolować typ obramowania nadawany oknu, należy ustawić jego właściwość WindowStyle przy użyciu jednej z następujących wartości wyliczenia WindowStyle:
- None
- SingleBorderWindow (domyślne)
- ThreeDBorderWindow
- ToolWindow
Efekt zastosowania stylu okna przedstawiono na poniższej ilustracji:
Zwróć uwagę, że powyższy obraz nie pokazuje zauważalnej różnicy między właściwościami SingleBorderWindow
i ThreeDBorderWindow
. W systemie Windows XP właściwość ThreeDBorderWindow
miała wpływ na sposób rysowania okna przez dodanie obramowania 3D do obszaru klienta. Począwszy od systemu Windows 7, różnice między dwoma stylami są minimalne.
Można ustawić właściwość WindowStyle przy użyciu znaczników XAML lub kodu. Ponieważ jest mało prawdopodobne, że ulegnie to zmianie w okresie istnienia okna, najprawdopodobniej skonfigurujesz to przy użyciu znaczników XAML.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowStyle="ToolWindow">
</Window>
Styl okna nieprostokątnego
Istnieją również sytuacje, gdy style obramowania, na które zezwala obiekt WindowStyle, są niewystarczające. Możesz na przykład utworzyć aplikację z obramowaniem nieprostokątnym, takie jak używane przez odtwarzacz Microsoft Windows Media Player.
Rozważmy na przykład okno dymka mowy pokazane na poniższej ilustracji:
Ten typ okna można utworzyć, ustawiając dla właściwości WindowStyle wartość None, i używając specjalnej obsługi, którą ma obiekt Window dla przezroczystości.
<Window x:Class="WindowsOverview.ClippedWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ClippedWindow" SizeToContent="WidthAndHeight"
WindowStyle="None" AllowsTransparency="True" Background="Transparent">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Rectangle Stroke="#FF000000" RadiusX="10" RadiusY="10"/>
<Path Fill="White" Stretch="Fill" Stroke="#FF000000" HorizontalAlignment="Left" Margin="15,-5.597,0,-0.003" Width="30" Grid.Row="1" Data="M22.166642,154.45381 L29.999666,187.66699 40.791059,154.54395"/>
<Rectangle Fill="White" RadiusX="10" RadiusY="10" Margin="1"/>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="25" Text="Greetings!" TextWrapping="Wrap" Margin="5,5,50,5"/>
<Button HorizontalAlignment="Right" VerticalAlignment="Top" Background="Transparent" BorderBrush="{x:Null}" Foreground="Red" Content="❌" FontSize="15" />
<Grid.Effect>
<DropShadowEffect BlurRadius="10" ShadowDepth="3" Color="LightBlue"/>
</Grid.Effect>
</Grid>
</Window>
Ta kombinacja wartości powoduje, że okno będzie renderowane jako przezroczyste. W tym stanie nie można używać przycisków zakończenia obszaru nieklienckiego okna i należy udostępnić własne.
Obecność na pasku zadań
Domyślny wygląd okna obejmuje przycisk paska zadań. Niektóre typy okien nie mają przycisku paska zadań, takie jak okna komunikatów, okna dialogowe lub okna, dla których dla właściwości WindowStyle ustawiono wartość ToolWindow. Możesz kontrolować, czy przycisk paska zadań dla okna jest wyświetlany, ustawiając właściwość ShowInTaskbar, która domyślnie ma wartość true
.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
ShowInTaskbar="False">
</Window>
Inne typy okien
NavigationWindow jest oknem przeznaczonym do hostowania zawartości z możliwością nawigacji.
Okna dialogowe to okna, które są często używane do zbierania informacji od użytkownika w celu ukończenia funkcji. Na przykład gdy użytkownik chce otworzyć plik, przez aplikację jest wyświetlane okno dialogowe Otwieranie pliku w celu uzyskania nazwy pliku od użytkownika. Aby uzyskać więcej informacji, zobacz Omówienie okien dialogowych.
Zobacz też
.NET Desktop feedback