최근에 내 WPF 응용 프로그램에 "app bar"로 데스크탑 가장자리에 도킹 할 수있는 창을 추가했습니다. 도킹을 수행하는 데 사용하는 코드는 this에서 발생했습니다.App Bar Window가 도킹 위치에서 튀어 나온 다음 도킹 위치로 이동합니다.
프로그램에는이 창과 관련된 세 가지 사용자 설정이 정의되어 있습니다. 하나는 윈도우가 도킹 된 가장자리이고 다른 두 개는 Left
& Top
속성의 값입니다. 아이디어는 창이 닫히거나 프로그램이 종료 될 때 프로그램이 다시 시작될 때 창이 같은 상태와 위치로 다시 열리는 것입니다.
내가 겪고있는 문제는 프로그램이 열리면 화면이 처음 임의의 위치에 표시된다는 것입니다 (윈도우가 생성 될 때 Windows에서 할당 된 좌표 일 것임). 도킹 된 위치. Trillian과 같은 앱 표시 줄 기능이있는 다른 프로그램은 처음부터 도킹 된 위치에 그려져 있습니다. 창문이 그렇게 움직이는 것을 보는 것은 약간 당황 스럽습니다. I는 this acrticle 판독으로 I는 윈도우가 활성화 SHAppBarrMessage
때, 또는 그 위치 및 크기 변화를 호출하는 기능을 추가 한
private void AppBarWindow_Activated(object sender, EventArgs e) {
if (Settings.Default.AppBarWindowEdge != ABEdge.None) {
AppBarFunctions.SendShellActivated(this);
}
}
private void AppBarWindow_Closing(object sender, CancelEventArgs e) {
Settings.Default.AppBarWindowLeft = Left;
Settings.Default.AppBarWindowTop = Top;
Settings.Default.Save();
AppBarFunctions.SetAppBar(this, ABEdge.None);
// Other, app specific code . . .
}
private void AppBarWindow_LocationChanged(object sender, EventArgs e) {
if (Settings.Default.AppBarWindowEdge != ABEdge.None) {
AppBarFunctions.SendShellWindowPosChanged(this);
}
}
private void AppBarWindow_SourceInitialized(object sender, EventArgs e) {
if (Settings.Default.AppBarWindowEdge != ABEdge.None) {
SizeWindow(Settings.Default.AppBarWindowEdge == ABEdge.None ? ABEdge.Left : ABEdge.None);
}
}
private void AppBarWindow_SizeChanged(object sender, SizeChangedEventArgs e) {
if (Settings.Default.AppBarWindowEdge != ABEdge.None) {
AppBarFunctions.SendShellWindowPosChanged(this);
}
}
private void SizeWindow(ABEdge originalEdge) {
// App specific code to compute the window's size . . .
if (originalEdge != Settings.Default.AppBarWindowEdge) {
AppBarFunctions.SetAppBar(this, Settings.Default.AppBarWindowEdge);
}
Settings.Default.AppBarWindowLeft = Left;
Settings.Default.AppBarWindowTop = Top;
Settings.Default.Save();
}
: 여기
창의 일부 코드이다. 통화가 동작에 아무런 영향을 미치지 않는 것 같아서 제거 할 수 있습니다.은 내가 SourceInitialized
및 Loading
이벤트가 창이 표시되기 전에 호출되지만 창 핸들 및 레이아웃 & 측정 패스 후 완료된 것을 알고있다. 그러나 AppBarFunctions.SetAppBar
에 대한 호출이 만들어지기 전에 윈도우가 렌더링 된 것으로 나타났습니다. 따라서 이것이 나타나고 그 자리로 이동하는 것을 볼 수 있습니다.
Left
및 Top
속성을 창 생성자의 설정에 저장된 값으로 설정하여 창을 도킹 된 위치로 이동하려고했습니다. 그것도 작동하지 않았다. 사실, 창문이 도킹 된 위치에 처음으로 그려지기 시작한 다음 데스크톱 가장자리에서 멀리 떨어진 곳으로 이동 한 다음 다시 도킹 된 위치로 다시 이동하는 것이 더 나빴습니다.
시작시이 창을 도킹 된 위치에 나타나게하고 나중에 이동하지 못하게하려면 어떻게해야합니까?
편집 :
문제의 원인을 찾았습니다. 창 Dispatcher
(UI 스레드)에서 DoResize
메서드에 대한 호출을 예약하기 바로 전에 ABSetPos
메서드의 클래스 코드에 주석이 있습니다. 그래서 분명히 WPF 또는 Windows 창에 예약되는 공간의 창 밖으로 이동
// This is done async, because WPF will send a resize after a new appbar is added.
// if we size right away, WPFs resize comes last and overrides us.
을, 나는 다음에 다시 이동 내 코드 & I에서 추적 점을 많이 추가 : 주석은 읽습니다. (코드의 주석에 언급 된) 이동이 일어날 때까지 윈도우가 렌더되지 않는다는 것을 알 수 있습니다. 윈도우가 렌더링 된 후, 코드에 의해 도킹 된 위치로 이동됩니다.
AppBarFunctions
클래스는 이미 셸의 메시지에 대한 wathcing에 대한 창 프로 시저 후크를 추가합니다. WM_WINDOWPOSCHANGED에 대한 검사를 추가하면 어떻게 든 메시지가 처리되지 않을 수 있습니까?또는 Windows/WPF에서 수행 한 이동에 대한 Left
및 Top
속성의 값을 변경할 수 있으므로 원하는대로 끝납니다.