앵커 요소가 이동할 때 WPF 팝업을 이동하려면 어떻게 해야 합니까?
다음과 같이 정의된 팝업이 있습니다.
<Popup
Name="myPopup"
StaysOpen="True"
Placement="Bottom"
PlacementRectangle="0,20,0,20"
PlacementTarget="{Binding ElementName=myPopupAnchor}">
<TextBlock ... />
</Popup>
를 이트핸에추습다에 했습니다.myPopupAnchor
- 이벤트에 요소MouseEnter
그리고.MouseLeave
두 개의 이벤트 핸들러가 팝업의 가시성을 전환합니다.
문제는 팝업이 처음 표시되거나 숨겨졌다가 다시 표시될 때만 내 팝업 앵커의 위치가 읽혀진다는 것입니다.앵커가 이동하면 팝업이 이동하지 않습니다.
이 문제를 해결할 방법을 찾고 있습니다. 움직이는 팝업을 원합니다.에 WPF를 수 ?PlacementTarget
바인딩이 변경되었으며 다시 읽어야 합니까?팝업 위치를 수동으로 설정할 수 있습니까?
현재 팝업을 닫았다가 다시 여는 매우 조잡한 해결 방법이 있어 재도장 문제가 발생합니다.
몇 가지 옵션과 샘플을 살펴봤습니다.제게 가장 효과적인 것은 팝업이 스스로 위치를 바꾸도록 만드는 속성 중 하나를 "점프"하는 것입니다.제가 사용한 속성은 Horizontal Offset입니다.
(자체 + 1)로 설정한 다음 원래 값으로 되돌립니다.창이 재배치될 때 실행되는 이벤트 핸들러에서 이 작업을 수행합니다.
// Reference to the PlacementTarget.
DependencyObject myPopupPlacementTarget;
// Reference to the popup.
Popup myPopup;
Window w = Window.GetWindow(myPopupPlacementTarget);
if (null != w)
{
w.LocationChanged += delegate(object sender, EventArgs args)
{
var offset = myPopup.HorizontalOffset;
myPopup.HorizontalOffset = offset + 1;
myPopup.HorizontalOffset = offset;
};
}
창이 이동되면 팝업 위치가 변경됩니다.창과 팝업이 이미 이동하고 있기 때문에 수평 간격띄우기의 미묘한 변화는 알 수 없습니다.
다른 상호 작용 중에 컨트롤이 열린 상태로 유지되는 경우 팝업 컨트롤이 가장 좋은 옵션인지 여부를 아직 평가 중입니다.저는 레이 번즈가 이런 것들을 아도너 층에 넣자는 제안이 몇몇 시나리오에서 좋은 접근법으로 보인다고 생각합니다.
네이쓴에게 덧붙이자면위의 AW의 훌륭한 솔루션은 이 경우 C# 코드를 어디에 배치해야 하는지와 같은 맥락을 지적해야 한다고 생각했습니다.저는 아직 WPF에 익숙하지 않아서 처음에는 Nathan을 어디에 배치해야 할지 고민했습니다.AW의 코드.내 팝업을 호스팅하는 사용자 컨트롤을 위한 생성자에 코드를 넣으려고 했을 때,Window.GetWindow()
반환된 상항반는되Null
(따라서 "codice_1" 코드는 실행되지 않았습니다.그래서 저는 다른 신인들이 상황에 맞게 사물을 보는 것이 이득이 될 수도 있다고 생각했습니다.
컨텍스트에서 C#을 표시하기 전에 다음은 관련 요소와 해당 이름을 표시하는 몇 가지 XAML 컨텍스트 예입니다.
<UserControl x:Class="MyNamespace.View1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<TextBlock x:Name="popupTarget" />
<Popup x:Name="myPopup"
Placement="Bottom"
PlacementTarget="{Binding ElementName=popupTarget}" >
(popup content here)
</Popup>
</UserControl>
그리고 비밀번호에서, 그들이 가지고 있는 것을 피하기 위해.Window.GetWindow()
돌아가다Null
Nathan을 수용하기 위해 Loaded 이벤트에 핸들러를 연결합니다.AW의 코드(예를 들어 유사한 스택 오버플로 토론에 대한 Peter Walke의 의견 참조).다음은 바로 내 UserControl 코드백의 모든 모습입니다.
public partial class View1 : UserControl
{
// Constructor
public View1()
{
InitializeComponent();
// Window.GetWindow() will return Null if you try to call it here!
// Wire up the Loaded handler instead
this.Loaded += new RoutedEventHandler(View1_Loaded);
}
/// Provides a way to "dock" the Popup control to the Window
/// so that the popup "sticks" to the window while the window is dragged around.
void View1_Loaded(object sender, RoutedEventArgs e)
{
Window w = Window.GetWindow(popupTarget);
// w should not be Null now!
if (null != w)
{
w.LocationChanged += delegate(object sender2, EventArgs args)
{
var offset = myPopup.HorizontalOffset;
// "bump" the offset to cause the popup to reposition itself
// on its own
myPopup.HorizontalOffset = offset + 1;
myPopup.HorizontalOffset = offset;
};
// Also handle the window being resized (so the popup's position stays
// relative to its target element if the target element moves upon
// window resize)
w.SizeChanged += delegate(object sender3, SizeChangedEventArgs e2)
{
var offset = myPopup.HorizontalOffset;
myPopup.HorizontalOffset = offset + 1;
myPopup.HorizontalOffset = offset;
};
}
}
}
private void ppValues_Opened(object sender, EventArgs e)
{
Window win = Window.GetWindow(YourControl);
win.LocationChanged += new EventHandler(win_LocationChanged);
}
void win_LocationChanged(object sender, EventArgs e)
{
if (YourPopup.IsOpen)
{
var mi = typeof(Popup).GetMethod("UpdatePosition", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
mi.Invoke(YourPopup, null);
}
}
팝업을 이동하려면 위치를 변경한 다음 다음 다음과 같이 설정하는 간단한 방법이 있습니다.
IsOpen = false;
IsOpen = true;
제이슨 프랭크의 대답에 덧붙이자면,Window.GetWindow()
WPF UserControl이 궁극적으로 WinForms ElementHost에서 호스팅되는 경우 접근 방식이 작동하지 않습니다.제가 찾아야 할 것은 스크롤 막대를 보여주는 요소인 사용자 컨트롤이 배치된 스크롤 뷰어였습니다.
이 일반적인 재귀 방법(다른 답변에서 수정됨)은 논리 트리에서 특정 유형의 부모를 찾고(시각적 트리도 사용할 수 있음), 찾으면 반환합니다.
public static T FindLogicalParentOf<T>(DependencyObject child) where T: FrameworkElement
{
DependencyObject parent = LogicalTreeHelper.GetParent(child);
//Top of the tree
if (parent == null) return null;
T parentWindow = parent as T;
if (parentWindow != null)
{
return parentWindow;
}
//Climb a step up
return FindLogicalParentOf<T>(parent);
}
대신 이 도우미 메서드를 호출합니다.Window.GetWindow()
올바른 이벤트를 구독한다는 제이슨의 대답을 계속합니다.ScrollViewer의 경우 ScrollChanged 이벤트입니다.
창이 활성화되지 않은 경우 팝업이 이미 포그라운드에 있기 때문에 Jason에서 코드를 수정했습니다.팝업 클래스에 옵션이 있습니까? 아니면 제 솔루션이 괜찮습니까?
private void FullLoaded(object sender, RoutedEventArgs e) {
Window CurrentWindow = Window.GetWindow(this.Popup);
if (CurrentWindow != null) {
CurrentWindow.LocationChanged += (object innerSender, EventArgs innerArgs) => {
this.RedrawPopup();
};
CurrentWindow.SizeChanged += (object innerSender, SizeChangedEventArgs innerArgs) => {
this.RedrawPopup();
};
CurrentWindow.Activated += (object innerSender, EventArgs innerArgs) => {
if (this.m_handleDeActivatedEvents && this.m_ShowOnActivated) {
this.Popup.IsOpen = true;
this.m_ShowOnActivated = false;
}
};
CurrentWindow.Deactivated += (object innerSender, EventArgs innerArgs) => {
if (this.m_handleDeActivatedEvents && this.Popup.IsOpen) {
this.Popup.IsOpen = false;
this.m_ShowOnActivated = true;
}
};
}
}
private void RedrawPopup() {
double Offset = this.Popup.HorizontalOffset;
this.Popup.HorizontalOffset = Offset + 1;
this.Popup.HorizontalOffset = Offset;
}
Jason Frank가 제공한 논리를 클래스에서 캡슐화하고 PopUp 클래스에서 상속했습니다.
class MyPopup : Popup
{
private Window _root;
public MyPopup()
{
Loaded += OnLoaded;
Unloaded += OnUnloaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
_root = Window.GetWindow(this);
_root.LocationChanged += OnRootLocationChanged;
}
private void OnRootLocationChanged(object sender, EventArgs e)
{
var offset = this.HorizontalOffset;
this.HorizontalOffset = offset + 1;
this.HorizontalOffset = offset;
}
private void OnUnloaded(object sender, RoutedEventArgs e)
{
_root.LocationChanged -= OnRootLocationChanged;
Loaded -= OnLoaded;
Unloaded -= OnUnloaded;
}
}
이러면 안 돼요.화면에 팝업이 표시될 때 상위 위치가 변경되면 팝업 자체의 위치가 변경되지 않습니다.이것이 팝업 컨트롤의 동작입니다.확인: http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.popup.aspx
문제를 해결할 수 있는 팝업 대신 창(WindowStyle=Window)을 사용할 수 있습니다.
다음 위치에서 팝업 팝업 위치 샘플 다운로드:
http://msdn.microsoft.com/en-us/library/ms771558(v=VS.90).aspx
코드 샘플은 Rect 개체와 함께 CustomPopupPlacement 클래스를 사용하고 수평 및 수직 오프셋에 바인딩하여 팝업을 이동합니다.
<Popup Name="popup1" Placement="Bottom" AllowsTransparency="True"
IsOpen="{Binding ElementName=popupOpen, Path=IsChecked}"
HorizontalOffset="{Binding ElementName=HOffset, Path=Value, Mode=TwoWay}"
VerticalOffset="{Binding ElementName=VOffset, Path=Value, Mode=TwoWay}"
언급URL : https://stackoverflow.com/questions/1600218/how-can-i-move-a-wpf-popup-when-its-anchor-element-moves
'programing' 카테고리의 다른 글
이 서비스를 사용할 수 있는 권한이 없습니다. iTunes 앱 업로드 오류 (0) | 2023.05.10 |
---|---|
SQL 서버:SQL 서버 백업 또는 복원 프로세스의 진행률을 확인하는 데 사용할 수 있는 SQL 스크립트가 있습니까? (0) | 2023.05.10 |
지속성을 위한 Redis Cache 및 Mongo용 아키텍처 (0) | 2023.05.10 |
아이폰: 현재 밀리초를 얻는 방법은? (0) | 2023.05.10 |
__dirname이(가) 노드 REPL에 정의되지 않은 이유는 무엇입니까? (0) | 2023.05.10 |