2011-03-17 135 views
18

我正尝试使用非标准下拉对齐创建ComboBox。基本上,我希望下拉菜单低于ComboBox,但与ComboBox的右边缘对齐,而不是左边缘。WPF组合框弹出式布局:底部并对齐到右边

正常ComboBox看起来像什么,用PlacementMode="Bottom"

combo box aligned to the left

我想要什么:

combobox aligned to the right

我想在我的ComboBox模板,以Popup.PlacementMode性能发挥,但没有任何可能的价值观似乎是我想要的。有没有简单的方法来完成它,最好是纯XAML?

回答

37

当我打开Expression Blend中,我想出了在几秒钟内的解决方案:

<Popup Placement="Left" VerticalOffset="{TemplateBinding ActualHeight}" 
     HorizontalOffset="{TemplateBinding ActualWidth}" 

有时候,这个应用程序是不是由手写XAML更加有用,但不是经常。 enter image description here

+0

这并不是我所要求的...查看我的问题中的图像 – 2011-03-17 19:24:50

+1

@Thomas Levesque好的,我附上了我的应用程序的截图。对不起,但我看不到你的第二个组合框和我的区别。 – vorrtex 2011-03-17 19:36:52

+0

对不起,我的错误...我错过了Placement =“Left”部分,它现在完美运行。优秀的答案,谢谢! – 2011-03-17 20:24:50

2

这是一个有点哈克,但确实有效。你只需要改变组合框样式。

<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> 

的弹出窗口Horizo​​ntalOffset只是要得到PopupContent.ActualWidth-PlacementTarget.ActualWidth的价值。为了得到那个价值,我使用了this trick from Charles Petzold

+0

谢谢,非常巧妙的解决方案...但也很可怕;) – 2011-03-17 19:15:34

+0

@Thomas如果你认为这很可怕....只是在开玩笑,你说,你不想要任何代码背后。如果您允许代码隐藏,只需创建一个具有PopupContent.ActualWidth-PlacementTarget.ActualWidth的Converter的MultiBinding。这样你的xaml看起来并不那么可怕,因为wohle虚拟元素被消除了。 – 2011-03-17 19:29:05

+0

转换器不算作代码隐藏;)。无论如何,我想要最简单的解决方案,并且vorrtex的答案是迄今为止最简单并且是纯粹的XAML,所以我接受了它 – 2011-03-17 21:40:06

4

我会使用“自定义” placementmode为弹出式,并宣布回调弹出控制放置在正确的位置,喜欢它的如下所示:WPF ComboBox DropDown Placement

看看这里的例子是为你工作:

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) } }; 
    } 
} 

希望这会有所帮助,至于

+0

感谢你的答案!我也想到了,但我更喜欢纯粹的XAML解决方案,而vorrtex的答案完全符合法案 – 2011-03-17 21:42:26

+0

很好的答案!e最简单的实现 – 2012-09-11 14:10:18

4

有人能后的完整的XAML代码吗?

我已经试过如下:

<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> 

......经过一番工作和测试中,我已经找到了一个很好的解决办法...

 <ComboBox.Style> 
      <Style TargetType="ComboBox" >          
       <Setter Property="Popup.FlowDirection" Value="RightToLeft"/>     
      </Style> 
     </ComboBox.Style>  
+0

只是复制原来的ComboBox模板并只修改弹出窗口(你可以在[默认主题](http://archive.msdn.microsoft.com/wpfsamples#themes)找到原始模板) – 2011-10-27 13:11:36

+0

@Sascha Krumbein欢迎来到stackoverflow。这不是一个论坛。如果您有特定的编程相关问题,请提出一个新问题。 – vidstige 2012-09-20 07:49:17

+0

这个答案似乎没有增加任何东西的顶部投票和接受的答案,它似乎更多的是一个问题。 Sascha,你可以尝试改进答案吗? – ANeves 2017-03-10 11:35:47