Подтвердить что ты не робот

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

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

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

поле со списком слева

Что я хочу:

combobox aligned right

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

Я бы использовал "Custom" placemode для PopUp и объявил обратный вызов, чтобы поместить всплывающее управление в нужную позицию, как показано здесь: 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) } };
    }
}

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

Ответ 3

Может кто-нибудь отправить полный код 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>      

Ответ 4

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

    <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. Чтобы получить это значение, я использовал этот трюк у Чарльза Петцольда.