24

我正在尝试ComboBox使用非标准下拉对齐创建一个。基本上,我希望下拉列表低于ComboBox,但与右边缘ComboBox而不是左边缘对齐。

正常的ComboBox样子,使用PlacementMode="Bottom"

组合框左对齐

我想要的是:

组合框向右对齐

我试图Popup.PlacementMode在 my 的模板中使用该属性ComboBox,但似乎没有一个可能的值符合我的要求。有没有一种简单的方法,最好是纯 XAML?

4

4 回答 4

45

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

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

有时,此应用程序比手动编写 xaml 更有用,但并不经常如此。 在此处输入图像描述

于 2011-03-17T19:14:59.700 回答
7

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

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

于 2011-03-17T20:04:02.337 回答
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>      
于 2011-10-27T12:37:15.523 回答
2

这有点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>

弹出窗口 Horizo​​ntalOffset 只需获取 PopupContent.ActualWidth-PlacementTarget.ActualWidth 的值。为了获得这个价值,我使用了 Charles Petzold 的这个技巧

于 2011-03-17T18:46:18.790 回答