动态设置弹出窗口的位置/位置 [英] Dynamically set the Popup position/placement
问题描述
Popup
控件默认为左对齐.它的左边缘与父对象的左边缘对齐.
我想做的是使控件右对齐,以便控件的右边缘与容器的右边缘对齐.
我希望它是动态的,因为我动态绑定了数据并且不知道弹出窗口的大小.
我尝试使用Opened
,SizeChanged
和Loaded
事件来获取Child
的宽度并将其设置为HorizontalOffset
,但是似乎存在计时问题.基本上,它在第一次加载控件时就可以正常运行,然后再加载(HorizontalOffset
设置为0)就可以了.
这是一个错误吗?我做错了吗?
编辑,我可以正常使用.似乎存在计时问题.如果我挂起Opened
事件并使用Dispatcher
异步设置HorizontalOffset
,则它会起作用:(
编辑2 我现在意识到自己在做一些愚蠢的事情.我希望ComboBox
的Popup
右对齐.我没有看到它在ArrangePopup
私有方法调用中被重新初始化.
我尝试从ComboBox
继承以覆盖放置函数,但是我必须做错了什么,因为尽管我覆盖了调用ArrangePopup
干杯.
我现在意识到,如果我不回答自己的问题,没有人能够将我的解决方法标记为答案.这是完整的代码.我将其实现为PRISM行为.
public static class PopupRightAlignBehavior
{
public static readonly DependencyProperty InstanceProperty =
DependencyProperty.RegisterAttached("Instance", typeof(object), typeof(PopupRightAlignBehavior), new PropertyMetadata(OnSetInstanceCallback));
public static object GetInstance(DependencyObject obj)
{
return (object)obj.GetValue(InstanceProperty);
}
public static void SetInstance(DependencyObject obj, object value)
{
obj.SetValue(InstanceProperty, value);
}
private static void OnSetInstanceCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var popup = (Popup)d;
popup.Opened -= OnPopupOpened;
popup.Opened += OnPopupOpened;
}
private static void OnPopupOpened(object sender, System.EventArgs e)
{
var popup = (Popup)sender;
popup.Dispatcher.BeginInvoke(() => popup.HorizontalOffset = -popup.ActualWidth);
}
}
The Popup
control is left-aligned by default. Its left edge is aligned with the left edge of its parent.
What I would like to do is to have the control right-aligned so that its right edge is aligned with the right edge of its container.
I want this to be dynamic because I dynamically bind the data and I don't know how big the popup will be.
I tried playing with the Opened
, SizeChanged
and Loaded
event to get the Child
's width and set it to the HorizontalOffset
but there seems to be timing issues. Basically it works fine the first time the control is loaded and then never after (the HorizontalOffset
is set to 0).
Is this a bug? Am I doing it the wrong way?
EDIT I got it working. It seems that there are timing issues. If I hook up the Opened
event and set the HorizontalOffset
asynchronously using the Dispatcher
, then it works :(
private static void OnPopupOpened(object sender, System.EventArgs e)
{
var popup = (Popup)sender;
popup.Dispatcher.BeginInvoke(() => popup.HorizontalOffset = -popup.ActualWidth);
}
EDIT 2 I now realise that I was doing something stupid. I wanted the Popup
of the ComboBox
to be right-aligned. I didn't see that it was reinitialized in the ArrangePopup
private method call.
I tried inheriting from ComboBox
to override the placement function but I must be doing something wrong because it still doesn't seem to work although I overrode the methods that call ArrangePopup
Cheers.
I now realize that if I don't answer to my own question no one will be able to mark my work-around as an answer. So here's the full code. I implemented it as a PRISM behavior.
public static class PopupRightAlignBehavior
{
public static readonly DependencyProperty InstanceProperty =
DependencyProperty.RegisterAttached("Instance", typeof(object), typeof(PopupRightAlignBehavior), new PropertyMetadata(OnSetInstanceCallback));
public static object GetInstance(DependencyObject obj)
{
return (object)obj.GetValue(InstanceProperty);
}
public static void SetInstance(DependencyObject obj, object value)
{
obj.SetValue(InstanceProperty, value);
}
private static void OnSetInstanceCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var popup = (Popup)d;
popup.Opened -= OnPopupOpened;
popup.Opened += OnPopupOpened;
}
private static void OnPopupOpened(object sender, System.EventArgs e)
{
var popup = (Popup)sender;
popup.Dispatcher.BeginInvoke(() => popup.HorizontalOffset = -popup.ActualWidth);
}
}
这篇关于动态设置弹出窗口的位置/位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!