XAML 是否可以根据WinUI3中的可用空间更改组合框弹出位置?

r3i60tvu  于 2022-12-07  发布在  其他
关注(0)|答案(1)|浏览(141)

组合框弹出窗口位置出现问题。在我的项目中,我希望组合框弹出窗口位于右侧或左侧,所以我决定更改弹出窗口的水平偏移量。弹出窗口将按我的预期偏移,但问题是当我指定水平偏移量的值时。弹出窗口无法根据可用空间调整位置。
这里我附加了指定offset值的代码,

<VisualStateGroup x:Name="DropDownStates">
    <VisualState x:Name="Opened">
        <VisualState.Setters>                                                
            <Setter Target="Popup.HorizontalOffset"
                    Value="50" />
         </VisualState.Setters>
    <Storyboard>                                                
    <SplitOpenThemeAnimation OpenedTargetName="PopupBorder"
                             ClosedTargetName="ContentPresenter"
                             OffsetFromCenter="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOffset}" />
    </Storyboard>
    </VisualState>
    <VisualState x:Name="Closed">
    <Storyboard>                                                
    <SplitCloseThemeAnimation OpenedTargetName="PopupBorder"
                                ClosedTargetName="ContentPresenter"
                                OffsetFromCenter="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DropDownOffset}" />
    </Storyboard>
    </VisualState>
</VisualStateGroup>

有什么建议可以克服这个问题吗?无论是XAML还是C#。

nue99wik

nue99wik1#

如果我们可以通过覆盖ControlTemplate来实现这一点,那就更好了,但我找不到一种方法。因此,让我建议您创建一个从ComboBox派生的控件。

    • 自定义组合框. cs**
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Media;
using System.Collections.Generic;
using System.Linq;

namespace ComboBoxTest;

public class CustomComboBox : ComboBox
{
    public CustomComboBox() : base()
    {
        this.Loaded += CustomComboBox_Loaded;
    }

    public static IEnumerable<T> FindChildrenOfType<T>(DependencyObject parent) where T : DependencyObject
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(parent, i);

            if (child is T hit)
            {
                yield return hit;
            }

            foreach (T? grandChild in FindChildrenOfType<T>(child))
            {
                yield return grandChild;
            }
        }
    }

    private void CustomComboBox_Loaded(object sender, RoutedEventArgs e)
    {
        if (FindChildrenOfType<Popup>(this).FirstOrDefault() is Popup popup)
        {
            popup.PlacementTarget = this;
            popup.DesiredPlacement = PopupPlacementMode.RightEdgeAlignedBottom;
        }
    }
}

而且就像平常的ComboBox一样使用它。

  • . xaml格式*
<local:CustomComboBox SelectedIndex="0">
    <ComboBoxItem Content="Text1" />
    <ComboBoxItem Content="Text2" />
    <ComboBoxItem Content="Text3" />
</local:CustomComboBox>

相关问题