Развертывание всплывающего окна WPF ComboBox: нижнее и выравнивание по правому краю
Я пытаюсь создать ComboBox
с нестандартным выравниванием выпадающего списка. В принципе, я хочу, чтобы выпадающее меню было ниже ComboBox
, но выровнено с правым краем ComboBox
вместо левого края.
Как выглядит обычный ComboBox
, используя PlacementMode="Bottom"
:
![поле со списком слева]()
Что я хочу:
![combobox aligned right]()
Я попытался сыграть с свойством Popup.PlacementMode
в шаблоне моего ComboBox
, но ни одно из возможных значений, похоже, не делает то, что я хочу. Есть ли простой способ сделать это, желательно в чистом XAML?
Ответы
Ответ 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. Чтобы получить это значение, я использовал этот трюк у Чарльза Петцольда.