Search code examples
c#wpfxamlcombobox

How to align combobox popup to bottom Left wpf?


Goal: To align combobox popup to bottom Left. Kindly check image below for reference:

enter image description here

What i tried?: I tried playing with Placement property of PART_Popup. If i set Placement="Bottom", the Popup is rendering from Bottom right. Check this image below:

enter image description here

Also, in VS Designer it is showing correctly:

enter image description here

ComboBox PART_Popup:

<Popup x:Name="PART_Popup"
       AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom"
       MinWidth="170">
    <themes:SystemDropShadowChrome x:Name="shadow" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}">
        <Border x:Name="dropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{StaticResource ComboBox.Static.Background}"
                CornerRadius="3">
            <ScrollViewer x:Name="DropDownScrollViewer" CanContentScroll="False">
                <Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
                    <Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
                        <Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}"
Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
                    </Canvas>
                    <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                    Margin="16"/>
                </Grid>
            </ScrollViewer>
        </Border>
    </themes:SystemDropShadowChrome>
</Popup>

XAML:

<ComboBox
HorizontalAlignment="Left" 
VerticalAlignment="Center" 
SelectedIndex="0"
Margin="50,0"
Style="{StaticResource FlatComboBoxStyle2}">
    <ComboBoxItem Content="Recent"/>
    <ComboBoxItem Content="Alphabetical"/>
</ComboBox>

I am looking for XAML code solution only. Thanks.


Solution

  • I fixed it by adding a converter in App.xaml.cs:

        public class PositiveToNegativeConverter:IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return (double) value > 0 ? 0 - (double) value : 0;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    

    And define it in my ComboBoxTemplate:

    <PositiveToNegativeConverter x:Key="PositiveToNegativeConverter" />
    

    And call it like this in Popup's HorizontalOffest:

    HorizontalOffset="{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource PositiveToNegativeConverter}}" 
    

    I hope this helps out anyone looking for solution.