Popup
控件默认为左对齐。它的左边缘与其父边缘的左边缘对齐。
我想要做的是让控件右对齐,使其右边缘与容器的右边缘对齐。
我希望这是动态的,因为我动态绑定数据,我不知道弹出窗口会有多大。
我尝试使用Opened
,SizeChanged
和Loaded
事件来获取Child
的宽度并将其设置为HorizontalOffset
,但似乎是计时问题。基本上它在第一次加载控件时工作正常,然后从不(HorizontalOffset
设置为0)。
这是一个错误吗?我这样做是错误的吗?
编辑我明白了。似乎有时间问题。如果我挂钩Opened
事件并使用HorizontalOffset
异步设置Dispatcher
,那么它可以正常工作:(
private static void OnPopupOpened(object sender, System.EventArgs e)
{
var popup = (Popup)sender;
popup.Dispatcher.BeginInvoke(() => popup.HorizontalOffset = -popup.ActualWidth);
}
private static void OnPopupOpened(object sender, System.EventArgs e)
{
var popup = (Popup)sender;
popup.Dispatcher.BeginInvoke(() => popup.HorizontalOffset = -popup.ActualWidth);
}
编辑2 我现在意识到我做的事情很愚蠢。我希望的{{1}}右对齐。我没有看到它在
Popup
私有方法调用中重新初始化
我尝试从ComboBox
继承来覆盖放置函数,但我必须做错了,因为尽管我覆盖了调用ArrangePopup
干杯。
答案 0 :(得分:3)
我现在意识到,如果我不回答我自己的问题,没有人能够将我的解决方案标记为答案。所以这是完整的代码。我将它实现为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);
}
}
答案 1 :(得分:0)
您可以使用MS Expression Blend生成ComboBox的默认模板。在模板中,您将找到名为Popup的Popup,将其FlowDirection属性更改为RightToLeft ...
<Popup x:Name="Popup" FlowDirection="RightToLeft">
注意Popup中的ScrollViewer对象将继承FlowDirection集,因此您必须将其FlowDirection显式设置为LeftToRight ......
<ScrollViewer x:Name="ScrollViewer" BorderThickness="0" Padding="1" FlowDirection="LeftToRight">
...否则它将从RightToLeft填充,滚动条将在左侧。