.NET WPF 세션 간 창 크기 기억
기본적으로 사용자가 내 응용프로그램의 창 크기를 조정할 때 응용프로그램을 다시 열 때 응용프로그램의 크기가 동일합니다.
처음에는 Size Changed 이벤트를 처리하고 Height와 Width를 저장하려고 했지만, 더 쉬운 해결책이 있을 것 같습니다.
꽤 간단한 문제지만, 저는 그것에 대한 쉬운 해결책을 찾을 수 없습니다.
user.config 파일에 값을 저장합니다.
설정 파일에 값을 만들어야 합니다. 값은 속성 폴더에 있어야 합니다.다섯 개의 값을 만듭니다.
TopdoubleLeftdoubleHeightdoubleWidthdoubleMaximizedbool창이 최대화되는지 여부를 유지합니다.더 많은 정보를 저장하려면 다른 유형 또는 구조가 필요합니다.
처음 두 개는 0으로 초기화하고 두 번째 두 개는 응용프로그램의 기본 크기로 초기화하고 마지막 두 개는 거짓으로 초기화합니다.
Window_OnSourceInitialized 이벤트 핸들러를 만들고 다음을 추가합니다.
this.Top = Properties.Settings.Default.Top;
this.Left = Properties.Settings.Default.Left;
this.Height = Properties.Settings.Default.Height;
this.Width = Properties.Settings.Default.Width;
// Very quick and dirty - but it does the job
if (Properties.Settings.Default.Maximized)
{
WindowState = WindowState.Maximized;
}
참고: 설정된 창 배치는 생성자가 아닌 창의 on source 초기화 이벤트에 들어가야 합니다. 그렇지 않으면 두 번째 모니터에서 창을 최대화하면 기본 모니터에서 창이 항상 다시 시작되고 액세스할 수 없습니다.
Window_Closing 이벤트 핸들러를 만들고 다음을 추가합니다.
if (WindowState == WindowState.Maximized)
{
// Use the RestoreBounds as the current values will be 0, 0 and the size of the screen
Properties.Settings.Default.Top = RestoreBounds.Top;
Properties.Settings.Default.Left = RestoreBounds.Left;
Properties.Settings.Default.Height = RestoreBounds.Height;
Properties.Settings.Default.Width = RestoreBounds.Width;
Properties.Settings.Default.Maximized = true;
}
else
{
Properties.Settings.Default.Top = this.Top;
Properties.Settings.Default.Left = this.Left;
Properties.Settings.Default.Height = this.Height;
Properties.Settings.Default.Width = this.Width;
Properties.Settings.Default.Maximized = false;
}
Properties.Settings.Default.Save();
응용 프로그램이 닫힌 상태에서 화면 연결을 끊거나 화면 해상도를 변경하여 표시 영역을 작게 만들면 이 작업이 실패하므로 값을 적용하기 전에 원하는 위치와 크기가 여전히 유효한지 확인해야 합니다.
실제로 설정 저장을 제외하고 코드백을 사용할 필요가 없습니다.사용자 지정 마크업 확장을 사용하여 창 크기와 위치를 다음과 같은 설정으로 바인딩할 수 있습니다.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:WpfApplication1"
Title="Window1"
Height="{my:SettingBinding Height}"
Width="{my:SettingBinding Width}"
Left="{my:SettingBinding Left}"
Top="{my:SettingBinding Top}">
이 마크업 확장에 대한 코드는 http://www.thomaslevesque.com/2008/11/18/wpf-binding-to-application-settings-using-a-markup-extension/ 에서 찾을 수 있습니다.
사용자 자신의 설정을 "롤링"하고 수동으로 어딘가에 저장할 수 있으며 일반적으로 작동하지만 모든 경우를 올바르게 처리하지 못하는 것은 매우 쉽습니다.종료 시 GetWindowPlacement()를 호출하고 시작 시 SetWindowPlacement()를 호출하여 OS가 작업을 수행하도록 하는 것이 훨씬 좋습니다.발생할 수 있는 모든 비정상적인 에지 사례(여러 모니터, 최대화된 상태에서 닫힌 경우 일반 창의 크기 저장 등)를 처리하여 사용자가 그럴 필요가 없습니다.
이 MSDN 샘플은 WPF 앱과 함께 사용하는 방법을 보여줍니다.샘플이 완벽하지 않습니다. 창이 처음 실행할 때 왼쪽 상단 모서리에서 가능한 작게 시작되고 설정 디자이너가 유형 값을 저장할 때 일부 이상한 동작이 발생합니다.WINDOWPLACEMENT), 하지만 적어도 시작은 해야 합니다.
Thomas가 위에 게시한 "긴 형식" 바인딩은 코딩이 거의 필요하지 않으므로 네임스페이스 바인딩이 있는지 확인하십시오.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:p="clr-namespace:WpfApplication1.Properties"
Title="Window1"
Height="{Binding Source={x:Static p:Settings.Default}, Path=Height, Mode=TwoWay}"
Width="{Binding Source={x:Static p:Settings.Default}, Path=Width, Mode=TwoWay}"
Left="{Binding Source={x:Static p:Settings.Default}, Path=Left, Mode=TwoWay}"
Top="{Binding Source={x:Static p:Settings.Default}, Path=Top, Mode=TwoWay}">
그런 다음 코드백을 절약하려면 다음과 같이 하십시오.
private void frmMain_Closed(object sender, EventArgs e)
{
Properties.Settings.Default.Save();
}
또는 다음과 같은 방법을 사용할 수도 있습니다(소스 참조).프로젝트에 WindowSettings 클래스를 추가하고 다음을 삽입합니다.WindowSettings.Save="True"기본 창의 머리글에서:
<Window x:Class="YOURPROJECT.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Services="clr-namespace:YOURNAMESPACE.Services"
Services:WindowSettings.Save="True">
여기서 창 설정은 다음과 같이 정의됩니다.
using System;
using System.ComponentModel;
using System.Configuration;
using System.Windows;
namespace YOURNAMESPACE.Services
{
/// <summary>
/// Persists a Window's Size, Location and WindowState to UserScopeSettings
/// </summary>
public class WindowSettings
{
#region Fields
/// <summary>
/// Register the "Save" attached property and the "OnSaveInvalidated" callback
/// </summary>
public static readonly DependencyProperty SaveProperty = DependencyProperty.RegisterAttached("Save", typeof (bool), typeof (WindowSettings), new FrameworkPropertyMetadata(OnSaveInvalidated));
private readonly Window mWindow;
private WindowApplicationSettings mWindowApplicationSettings;
#endregion Fields
#region Constructors
public WindowSettings(Window pWindow) { mWindow = pWindow; }
#endregion Constructors
#region Properties
[Browsable(false)] public WindowApplicationSettings Settings {
get {
if (mWindowApplicationSettings == null) mWindowApplicationSettings = CreateWindowApplicationSettingsInstance();
return mWindowApplicationSettings;
}
}
#endregion Properties
#region Methods
public static void SetSave(DependencyObject pDependencyObject, bool pEnabled) { pDependencyObject.SetValue(SaveProperty, pEnabled); }
protected virtual WindowApplicationSettings CreateWindowApplicationSettingsInstance() { return new WindowApplicationSettings(this); }
/// <summary>
/// Load the Window Size Location and State from the settings object
/// </summary>
protected virtual void LoadWindowState() {
Settings.Reload();
if (Settings.Location != Rect.Empty) {
mWindow.Left = Settings.Location.Left;
mWindow.Top = Settings.Location.Top;
mWindow.Width = Settings.Location.Width;
mWindow.Height = Settings.Location.Height;
}
if (Settings.WindowState != WindowState.Maximized) mWindow.WindowState = Settings.WindowState;
}
/// <summary>
/// Save the Window Size, Location and State to the settings object
/// </summary>
protected virtual void SaveWindowState() {
Settings.WindowState = mWindow.WindowState;
Settings.Location = mWindow.RestoreBounds;
Settings.Save();
}
/// <summary>
/// Called when Save is changed on an object.
/// </summary>
private static void OnSaveInvalidated(DependencyObject pDependencyObject, DependencyPropertyChangedEventArgs pDependencyPropertyChangedEventArgs) {
var window = pDependencyObject as Window;
if (window != null)
if ((bool) pDependencyPropertyChangedEventArgs.NewValue) {
var settings = new WindowSettings(window);
settings.Attach();
}
}
private void Attach() {
if (mWindow != null) {
mWindow.Closing += WindowClosing;
mWindow.Initialized += WindowInitialized;
mWindow.Loaded += WindowLoaded;
}
}
private void WindowClosing(object pSender, CancelEventArgs pCancelEventArgs) { SaveWindowState(); }
private void WindowInitialized(object pSender, EventArgs pEventArgs) { LoadWindowState(); }
private void WindowLoaded(object pSender, RoutedEventArgs pRoutedEventArgs) { if (Settings.WindowState == WindowState.Maximized) mWindow.WindowState = Settings.WindowState; }
#endregion Methods
#region Nested Types
public class WindowApplicationSettings : ApplicationSettingsBase
{
#region Constructors
public WindowApplicationSettings(WindowSettings pWindowSettings) { }
#endregion Constructors
#region Properties
[UserScopedSetting] public Rect Location {
get {
if (this["Location"] != null) return ((Rect) this["Location"]);
return Rect.Empty;
}
set { this["Location"] = value; }
}
[UserScopedSetting] public WindowState WindowState {
get {
if (this["WindowState"] != null) return (WindowState) this["WindowState"];
return WindowState.Normal;
}
set { this["WindowState"] = value; }
}
#endregion Properties
}
#endregion Nested Types
}
}
NuGet Project Restore Windows Place는 이 모든 것을 지원하며 XML 파일에 정보를 저장합니다.
창에서 작동하려면 다음을 호출하는 것처럼 간단합니다.
((App)Application.Current).WindowPlace.Register(this);
앱에서 창을 관리하는 클래스를 만듭니다.자세한 내용은 위의 github 링크를 참조하십시오.
저는 RandomEngys의 훌륭한 답변을 바탕으로 더 일반적인 솔루션을 만들었습니다.그러면 파일 위치가 실행 중인 폴더에 저장되므로 새 창마다 새 속성을 만들 필요가 없습니다.이 솔루션은 코드 뒤에 있는 최소한의 코드로 저에게 매우 유용합니다.
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Interop;
using System.Xml;
using System.Xml.Serialization;
namespace WindowPlacementNameSpace
{
// RECT structure required by WINDOWPLACEMENT structure
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public RECT(int left, int top, int right, int bottom)
{
this.Left = left;
this.Top = top;
this.Right = right;
this.Bottom = bottom;
}
}
// POINT structure required by WINDOWPLACEMENT structure
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
}
// WINDOWPLACEMENT stores the position, size, and state of a window
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPLACEMENT
{
public int length;
public int flags;
public int showCmd;
public POINT minPosition;
public POINT maxPosition;
public RECT normalPosition;
}
public static class WindowPlacement
{
private static readonly Encoding Encoding = new UTF8Encoding();
private static readonly XmlSerializer Serializer = new XmlSerializer(typeof(WINDOWPLACEMENT));
[DllImport("user32.dll")]
private static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);
[DllImport("user32.dll")]
private static extern bool GetWindowPlacement(IntPtr hWnd, out WINDOWPLACEMENT lpwndpl);
private const int SW_SHOWNORMAL = 1;
private const int SW_SHOWMINIMIZED = 2;
private static void SetPlacement(IntPtr windowHandle, string placementXml)
{
if (string.IsNullOrEmpty(placementXml))
{
return;
}
byte[] xmlBytes = Encoding.GetBytes(placementXml);
try
{
WINDOWPLACEMENT placement;
using (MemoryStream memoryStream = new MemoryStream(xmlBytes))
{
placement = (WINDOWPLACEMENT)Serializer.Deserialize(memoryStream);
}
placement.length = Marshal.SizeOf(typeof(WINDOWPLACEMENT));
placement.flags = 0;
placement.showCmd = (placement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWNORMAL : placement.showCmd);
SetWindowPlacement(windowHandle, ref placement);
}
catch (InvalidOperationException)
{
// Parsing placement XML failed. Fail silently.
}
}
private static string GetPlacement(IntPtr windowHandle)
{
WINDOWPLACEMENT placement;
GetWindowPlacement(windowHandle, out placement);
using (MemoryStream memoryStream = new MemoryStream())
{
using (XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8))
{
Serializer.Serialize(xmlTextWriter, placement);
byte[] xmlBytes = memoryStream.ToArray();
return Encoding.GetString(xmlBytes);
}
}
}
public static void ApplyPlacement(this Window window)
{
var className = window.GetType().Name;
try
{
var pos = File.ReadAllText(Directory + "\\" + className + ".pos");
SetPlacement(new WindowInteropHelper(window).Handle, pos);
}
catch (Exception exception)
{
Log.Error("Couldn't read position for " + className, exception);
}
}
public static void SavePlacement(this Window window)
{
var className = window.GetType().Name;
var pos = GetPlacement(new WindowInteropHelper(window).Handle);
try
{
File.WriteAllText(Directory + "\\" + className + ".pos", pos);
}
catch (Exception exception)
{
Log.Error("Couldn't write position for " + className, exception);
}
}
private static string Directory => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
}
}
뒤에 있는 코드에서 이 두 가지 방법을 추가합니다.
///This method is save the actual position of the window to file "WindowName.pos"
private void ClosingTrigger(object sender, EventArgs e)
{
this.SavePlacement();
}
///This method is load the actual position of the window from the file
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
this.ApplyPlacement();
}
xaml 창에서 이것을 추가합니다.
Closing="ClosingTrigger"
기본 해결 방법은 설정 파일을 사용하는 것입니다.설정 파일의 문제는 모든 설정을 정의하고 데이터를 앞뒤로 복사하는 코드를 직접 작성해야 한다는 것입니다.추적해야 할 속성이 많은 경우 상당히 지루합니다.
저는 이를 위해 매우 유연하고 사용하기 쉬운 라이브러리를 만들었습니다. 어떤 개체의 속성을 추적할지 알려주면 나머지를 수행할 수 있습니다.원하는 경우 구성할 수도 있습니다.
도서관 이름은 Jot (github)이고, 여기 제가 쓴 오래된 CodeProject 기사가 있습니다.
창 크기와 위치를 추적하기 위해 사용하는 방법은 다음과 같습니다.
public MainWindow()
{
InitializeComponent();
_stateTracker.Configure(this)
.IdentifyAs("MyMainWindow")
.AddProperties(nameof(Height), nameof(Width), nameof(Left), nameof(Top), nameof(WindowState))
.RegisterPersistTrigger(nameof(Closed))
.Apply();
}
Jot vs. 설정 파일:Jot의 경우 코드가 상당히 적으며 각 속성을 한 번만 언급하면 되므로 오류가 발생할 가능성이 훨씬 적습니다.설정 파일의 경우 속성을 명시적으로 만들 때 한 번, 값을 앞뒤로 복사하는 코드에서 추가로 네 번 각 속성을 5번 언급해야 합니다.
스토리지, 직렬화 등을 완벽하게 구성할 수 있습니다.또한 IOC를 사용할 때 확인되는 모든 개체에 추적을 자동으로 적용하도록 연결할 수도 있으므로 속성을 영구적으로 유지하려면 [Trackable] 특성을 적용하기만 하면 됩니다.
제가 이 모든 것을 쓰는 이유는 도서관이 최고라고 생각하고 그것에 대해 입 밖에 내고 싶지 않기 때문입니다.
저는 이것을 하는 빠른 수업을 썼습니다.이름은 다음과 같습니다.
public MainWindow()
{
FormSizeSaver.RegisterForm(this, () => Settings.Default.MainWindowSettings,
s =>
{
Settings.Default.MainWindowSettings = s;
Settings.Default.Save();
});
InitializeComponent();
...
코드는 다음과 같습니다.
public class FormSizeSaver
{
private readonly Window window;
private readonly Func<FormSizeSaverSettings> getSetting;
private readonly Action<FormSizeSaverSettings> saveSetting;
private FormSizeSaver(Window window, Func<string> getSetting, Action<string> saveSetting)
{
this.window = window;
this.getSetting = () => FormSizeSaverSettings.FromString(getSetting());
this.saveSetting = s => saveSetting(s.ToString());
window.Initialized += InitializedHandler;
window.StateChanged += StateChangedHandler;
window.SizeChanged += SizeChangedHandler;
window.LocationChanged += LocationChangedHandler;
}
public static FormSizeSaver RegisterForm(Window window, Func<string> getSetting, Action<string> saveSetting)
{
return new FormSizeSaver(window, getSetting, saveSetting);
}
private void SizeChangedHandler(object sender, SizeChangedEventArgs e)
{
var s = getSetting();
s.Height = e.NewSize.Height;
s.Width = e.NewSize.Width;
saveSetting(s);
}
private void StateChangedHandler(object sender, EventArgs e)
{
var s = getSetting();
if (window.WindowState == WindowState.Maximized)
{
if (!s.Maximized)
{
s.Maximized = true;
saveSetting(s);
}
}
else if (window.WindowState == WindowState.Normal)
{
if (s.Maximized)
{
s.Maximized = false;
saveSetting(s);
}
}
}
private void InitializedHandler(object sender, EventArgs e)
{
var s = getSetting();
window.WindowState = s.Maximized ? WindowState.Maximized : WindowState.Normal;
if (s.Height != 0 && s.Width != 0)
{
window.Height = s.Height;
window.Width = s.Width;
window.WindowStartupLocation = WindowStartupLocation.Manual;
window.Left = s.XLoc;
window.Top = s.YLoc;
}
}
private void LocationChangedHandler(object sender, EventArgs e)
{
var s = getSetting();
s.XLoc = window.Left;
s.YLoc = window.Top;
saveSetting(s);
}
}
[Serializable]
internal class FormSizeSaverSettings
{
public double Height, Width, YLoc, XLoc;
public bool Maximized;
public override string ToString()
{
using (var ms = new MemoryStream())
{
var bf = new BinaryFormatter();
bf.Serialize(ms, this);
ms.Position = 0;
byte[] buffer = new byte[(int)ms.Length];
ms.Read(buffer, 0, buffer.Length);
return Convert.ToBase64String(buffer);
}
}
internal static FormSizeSaverSettings FromString(string value)
{
try
{
using (var ms = new MemoryStream(Convert.FromBase64String(value)))
{
var bf = new BinaryFormatter();
return (FormSizeSaverSettings) bf.Deserialize(ms);
}
}
catch (Exception)
{
return new FormSizeSaverSettings();
}
}
}
기본 설정에서 WindowXml이라는 문자열을 만듭니다.
Window Loaded(윈도우 로드됨) 및 Closing(닫기) 이벤트에서 이 확장 방법을 사용하여 Window(윈도우) 크기와 위치를 복원하고 저장합니다.
using YourProject.Properties;
using System;
using System.Linq;
using System.Windows;
using System.Xml.Linq;
namespace YourProject.Extensions
{
public static class WindowExtensions
{
public static void SaveSizeAndLocation(this Window w)
{
try
{
var s = "<W>";
s += GetNode("Top", w.WindowState == WindowState.Maximized ? w.RestoreBounds.Top : w.Top);
s += GetNode("Left", w.WindowState == WindowState.Maximized ? w.RestoreBounds.Left : w.Left);
s += GetNode("Height", w.WindowState == WindowState.Maximized ? w.RestoreBounds.Height : w.Height);
s += GetNode("Width", w.WindowState == WindowState.Maximized ? w.RestoreBounds.Width : w.Width);
s += GetNode("WindowState", w.WindowState);
s += "</W>";
Settings.Default.WindowXml = s;
Settings.Default.Save();
}
catch (Exception)
{
}
}
public static void RestoreSizeAndLocation(this Window w)
{
try
{
var xd = XDocument.Parse(Settings.Default.WindowXml);
w.WindowState = (WindowState)Enum.Parse(typeof(WindowState), xd.Descendants("WindowState").FirstOrDefault().Value);
w.Top = Convert.ToDouble(xd.Descendants("Top").FirstOrDefault().Value);
w.Left = Convert.ToDouble(xd.Descendants("Left").FirstOrDefault().Value);
w.Height = Convert.ToDouble(xd.Descendants("Height").FirstOrDefault().Value);
w.Width = Convert.ToDouble(xd.Descendants("Width").FirstOrDefault().Value);
}
catch (Exception)
{
}
}
private static string GetNode(string name, object value)
{
return string.Format("<{0}>{1}</{0}>", name, value);
}
}
}
다음과 같이 하십시오.
public class WindowStateHelper
{
public static string ToXml(System.Windows.Window win)
{
XElement bounds = new XElement("Bounds");
if (win.WindowState == System.Windows.WindowState.Maximized)
{
bounds.Add(new XElement("Top", win.RestoreBounds.Top));
bounds.Add(new XElement("Left", win.RestoreBounds.Left));
bounds.Add(new XElement("Height", win.RestoreBounds.Height));
bounds.Add(new XElement("Width", win.RestoreBounds.Width));
}
else
{
bounds.Add(new XElement("Top", win.Top));
bounds.Add(new XElement("Left", win.Left));
bounds.Add(new XElement("Height", win.Height));
bounds.Add(new XElement("Width", win.Width));
}
XElement root = new XElement("WindowState",
new XElement("State", win.WindowState.ToString()),
new XElement("Visibility", win.Visibility.ToString()),
bounds);
return root.ToString();
}
public static void FromXml(string xml, System.Windows.Window win)
{
try
{
XElement root = XElement.Parse(xml);
string state = root.Descendants("State").FirstOrDefault().Value;
win.WindowState = (System.Windows.WindowState)Enum.Parse(typeof(System.Windows.WindowState), state);
state = root.Descendants("Visibility").FirstOrDefault().Value;
win.Visibility = (System.Windows.Visibility)Enum.Parse(typeof(System.Windows.Visibility), state);
XElement bounds = root.Descendants("Bounds").FirstOrDefault();
win.Top = Convert.ToDouble(bounds.Element("Top").Value);
win.Left = Convert.ToDouble(bounds.Element("Left").Value);
win.Height = Convert.ToDouble(bounds.Element("Height").Value);
win.Width = Convert.ToDouble(bounds.Element("Width").Value);
}
catch (Exception x)
{
System.Console.WriteLine(x.ToString());
}
}
}
앱이 닫힐 때:
Properties.Settings.Default.Win1Placement = WindowStateHelper.ToXml(win1);
Properties.Settings.Default.Win2Placement = WindowStateHelper.ToXml(win2);
...
앱이 시작될 때:
WindowStateHelper.FromXml(Properties.Settings.Default.Win1Placement, win1);
WindowStateHelper.FromXml(Properties.Settings.Default.Win2Placement, win2);
...
저는 랜스 클리블랜드의 답변을 사용하여 설정을 바인딩하고 있습니다.그러나 내 창이 화면 밖으로 나오지 않도록 코드를 더 사용하고 있습니다.
private void SetWindowSettingsIntoScreenArea()
{
// first detect Screen, where we will display the Window
// second correct bottom and right position
// then the top and left position.
// If Size is bigger than current Screen, it's still possible to move and size the Window
// get the screen to display the window
var screen = System.Windows.Forms.Screen.FromPoint(new System.Drawing.Point((int)Default.Left, (int)Default.Top));
// is bottom position out of screen for more than 1/3 Height of Window?
if (Default.Top + (Default.Height / 3) > screen.WorkingArea.Height)
Default.Top = screen.WorkingArea.Height - Default.Height;
// is right position out of screen for more than 1/2 Width of Window?
if (Default.Left + (Default.Width / 2) > screen.WorkingArea.Width)
Default.Left = screen.WorkingArea.Width - Default.Width;
// is top position out of screen?
if (Default.Top < screen.WorkingArea.Top)
Default.Top = screen.WorkingArea.Top;
// is left position out of screen?
if (Default.Left < screen.WorkingArea.Left)
Default.Left = screen.WorkingArea.Left;
}
언급URL : https://stackoverflow.com/questions/847752/net-wpf-remember-window-size-between-sessions
'source' 카테고리의 다른 글
| 후드 아래에서 잠금 문은 무엇을 합니까? (0) | 2023.05.05 |
|---|---|
| psql: 서버에 연결할 수 없습니다.해당 파일 또는 디렉터리 없음(Mac OS X) (0) | 2023.05.05 |
| 모든 디렉토리 및 파일을 재귀적으로 복사하려면 어떻게 해야 합니까? (0) | 2023.04.25 |
| Linux python3 - lib 'SQL Server'를 열 수 없습니다. (0) | 2023.04.25 |
| WPF 창의 핸들을 찾는 중입니다. (0) | 2023.04.25 |