WPF ComboBox 弹出位置:底部并与右边缘对齐
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5340640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF ComboBox popup placement : Bottom and aligned to the right edge
提问by Thomas Levesque
I'm trying to create a ComboBox
with a non-standard dropdown alignment. Basically, I want the dropdown to be below the ComboBox
, but aligned with the right edge of the ComboBox
instead of the left edge.
我正在尝试创建一个ComboBox
非标准下拉对齐方式。基本上,我希望下拉菜单位于 下方ComboBox
,但与 的右边缘ComboBox
而不是左边缘对齐。
What a normal ComboBox
looks like, using PlacementMode="Bottom"
:
什么是正常的ComboBox
,使用PlacementMode="Bottom"
:
What I want:
我想要的是:
I tried to play with the Popup.PlacementMode
property in the template of my ComboBox
, but none of the possible values seem to do what I want. Is there a simple way to do it, preferably in pure XAML?
我试图Popup.PlacementMode
在 my 的模板中使用该属性ComboBox
,但似乎没有一个可能的值符合我的要求。有没有一种简单的方法可以做到这一点,最好是在纯 XAML 中?
回答by vortexwolf
When I opened Expression Blend, I have come up with the solution within a few seconds:
当我打开 Expression Blend 时,我在几秒钟内就想出了解决方案:
<Popup Placement="Left" VerticalOffset="{TemplateBinding ActualHeight}"
HorizontalOffset="{TemplateBinding ActualWidth}"
Sometimes this application is more useful than writing xaml by hands, but not so often.
有时这个应用程序比手工编写 xaml 更有用,但不是那么频繁。
回答by serge_gubenko
I would use the "Custom" placementmode for the PopUp and declare a callback to place the popup control into the correct position, like it's shown here: WPF ComboBox DropDown Placement
我会为 PopUp 使用“自定义”放置模式并声明一个回调以将弹出控件放置到正确的位置,如下所示:WPF ComboBox DropDown Placement
See if an example here would work for you:
看看这里的一个例子是否适合你:
public class TestComboBox : ComboBox
{
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var popup = (Popup)Template.FindName("PART_Popup", this);
popup.Placement = PlacementMode.Custom;
popup.CustomPopupPlacementCallback += (Size popupSize, Size targetSize, Point offset) =>
new[] { new CustomPopupPlacement() { Point = new Point (targetSize.Width-popupSize.Width, targetSize.Height) } };
}
}
hope this helps, regards
希望这有帮助,问候
回答by Sascha Krumbein
Can someone post the complete xaml code please?
有人可以发布完整的xaml代码吗?
I've tried the following:
我尝试了以下方法:
<ComboBox Grid.Column="1" Height="24" Width="20" HorizontalAlignment="Right"
VerticalAlignment="Top"
Name="comboBox2"
ItemsSource="{Binding Source={StaticResource FilterTypes}}"
SelectedValue="{Binding Path=SelectedType, Mode=TwoWay}" >
<ComboBox.Template>
<ControlTemplate>
<Popup Placement="Left" VerticalOffset="{TemplateBinding ActualHeight}"
HorizontalOffset="{TemplateBinding ActualWidth}" />
</ControlTemplate>
</ComboBox.Template>
</ComboBox>
... after some working and testing I've found a good solution...
...经过一些工作和测试,我找到了一个很好的解决方案......
<ComboBox.Style>
<Style TargetType="ComboBox" >
<Setter Property="Popup.FlowDirection" Value="RightToLeft"/>
</Style>
</ComboBox.Style>
回答by Markus Hütter
it's a little hacky, but does work. you just have to change the combobox style.
它有点hacky,但确实有效。您只需要更改组合框样式。
<Grid Height="40">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<FrameworkElement Name="dummy" Visibility="Collapsed">
<FrameworkElement.RenderTransform>
<TransformGroup x:Name="xformgrp">
<TranslateTransform X="{Binding ElementName=PopupContent, Path=ActualWidth}" />
<ScaleTransform ScaleX="-1" />
<TranslateTransform X="{Binding ElementName=chk, Path=ActualWidth}" />
</TransformGroup>
</FrameworkElement.RenderTransform>
</FrameworkElement>
<CheckBox Name="chk" HorizontalAlignment="Center">checkthisout</CheckBox>
<Popup IsOpen="{Binding IsChecked, ElementName=chk}" PlacementTarget="{Binding ElementName=chk}" Placement="Bottom" HorizontalOffset="{Binding ElementName=dummy, Path=RenderTransform.Value.OffsetX}">
<TextBlock Name="PopupContent" Foreground="Yellow" Background="Blue">yeah long popupcontent</TextBlock>
</Popup>
</Grid>
</Grid>
The popups HorizontalOffset just has to get the value of PopupContent.ActualWidth-PlacementTarget.ActualWidth. To get that value I used this trick from Charles Petzold.
弹出窗口 HorizontalOffset 只需要获取 PopupContent.ActualWidth-PlacementTarget.ActualWidth 的值。为了获得这个价值,我使用了 Charles Petzold 的这个技巧。