WPF ComboBox 弹出位置:底部并与右边缘对齐

发布于 2024-10-23 14:31:10 字数 589 浏览 3 评论 0原文

我正在尝试创建一个具有非标准下拉对齐的 ComboBox 。基本上,我希望下拉菜单位于 ComboBox 下方,但与 ComboBox 的右边缘而不是左边缘对齐。

使用 PlacementMode="Bottom" 时,正常的 ComboBox 是什么样子:

组合框左对齐

我想要的:

组合框右对齐

I尝试使用我的 ComboBox 模板中的 Popup.PlacementMode 属性,但所有可能的值似乎都无法达到我想要的效果。有没有一种简单的方法可以做到这一点,最好是使用纯 XAML?

I'm trying to create a ComboBox with a non-standard dropdown alignment. Basically, I want the dropdown to be below the ComboBox, but aligned with the right edge of the ComboBox instead of the left edge.

What a normal ComboBox looks like, using PlacementMode="Bottom":

combo box aligned to the left

What I want:

combobox aligned to the right

I tried to play with the Popup.PlacementMode property in the template of my ComboBox, but none of the possible values seem to do what I want. Is there a simple way to do it, preferably in pure XAML?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

紫罗兰の梦幻 2024-10-30 14:31:11

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

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

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

When I opened Expression Blend, I have come up with the solution within a few seconds:

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

Sometimes this application is more useful than writing xaml by hands, but not so often.
enter image description here

余厌 2024-10-30 14:31:11

我将使用 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) } };
    }
}

希望这有帮助,问候

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

留蓝 2024-10-30 14:31:11

有人可以发布完整的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>      

Can someone post the complete xaml code please?

I've tried the following:

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

... after some working and testing I've found a good solution...

        <ComboBox.Style>
            <Style TargetType="ComboBox" >                                    
                <Setter Property="Popup.FlowDirection" Value="RightToLeft"/>                  
            </Style>
        </ComboBox.Style>      
梦一生花开无言 2024-10-30 14:31:11

这有点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 的值。为了获得该值,我使用了 this查尔斯·佩措尔德的把戏

it's a little hacky, but does work. you just have to change the combobox style.

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

The popups HorizontalOffset just has to get the value of PopupContent.ActualWidth-PlacementTarget.ActualWidth. To get that value I used this trick from Charles Petzold.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文