Расположение всплывающего окна WPF ComboBox: снизу и выровнено по правому краю - PullRequest
21 голосов
/ 17 марта 2011

Я пытаюсь создать ComboBox с нестандартным выпадающим выравниванием.По сути, я хочу, чтобы раскрывающийся список был ниже ComboBox, но выровнен по правому краю ComboBox вместо левого.

Как выглядит нормальный ComboBox, используя PlacementMode="Bottom":

combo box aligned to the left

Что я хочу:

combobox aligned to the right

Я пыталсяпоиграйте со свойством Popup.PlacementMode в шаблоне моего ComboBox, но ни одно из возможных значений, кажется, не выполняет то, что я хочу.Есть ли простой способ сделать это, предпочтительно в чистом XAML?

Ответы [ 4 ]

41 голосов
/ 17 марта 2011

Когда я открыл Expression Blend, я нашел решение за несколько секунд:

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

Иногда это приложение более полезно, чем написание xaml руками, но не так часто.enter image description here

5 голосов
/ 17 марта 2011

Я бы использовал «Пользовательский» режим размещения для всплывающего окна и объявил бы обратный вызов для размещения всплывающего элемента управления в правильное положение, как показано здесь: 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) } };
    }
}

надеюсь, это поможет, с уважением

4 голосов
/ 27 октября 2011

Может кто-нибудь опубликовать полный код 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>      
2 голосов
/ 17 марта 2011

немного хакерски, но работает. вам просто нужно изменить стиль комбинированного списка.

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

Всплывающие окна HorizontalOffset просто должны получить значение PopupContent.ActualWidth-PlacementTarget.ActualWidth. Чтобы получить это значение, я использовал этот трюк от Чарльза Петцольда .

...