XAML 在WPF中创建水平项目控件/组合框

gpfsuwkq  于 2023-06-19  发布在  其他
关注(0)|答案(1)|浏览(97)

我需要一个项目控制 * 弹出 *(因为我需要在一个数据网格中使用它,所以当它被扩展的列宽不受影响),这表明项目水平。理想情况下,它应该是带有水平“下拉”的组合框。更好的是,如果它不下拉,但弹出以上的组合按钮的中心(选择项目或Esc键将关闭它)。项目是固定大小的正方形30x30,数量很少,所以不需要滚动视图。
我发现这个“代码”根本不起作用(屏幕上没有任何渲染):

<ComboBox HorizontalAlignment="Left" VerticalAlignment="Top" Width="120">
    <ComboBox.Items>
        <ComboBoxItem>Item 1</ComboBoxItem>
        <ComboBoxItem>Item 2</ComboBoxItem>
        <ComboBoxItem>Item 3</ComboBoxItem>
    </ComboBox.Items>
    <ComboBox.ItemContainerStyle>
        <Style TargetType="{x:Type ComboBoxItem}">
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
        </Style>
    </ComboBox.ItemContainerStyle>
    <ComboBox.Template>
        <ControlTemplate TargetType="{x:Type ComboBox}">
            <Grid>
                <Popup x:Name="PART_Popup" AllowsTransparency="true" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Bottom">
                    <Border x:Name="DropDownBorder" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1">
                        <ScrollViewer x:Name="DropDownScrollViewer">
                            <StackPanel IsItemsHost="true"/>
                        </ScrollViewer>
                    </Border>
                </Popup>
            </Grid>
        </ControlTemplate>
    </ComboBox.Template>
</ComboBox>

如何让它工作?

bwntbbo3

bwntbbo31#

此行为应解决弹出窗口定位问题。

using Microsoft.Xaml.Behaviors;
using System;
using System.Runtime.Versioning;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Media3D;

namespace MCS.UI.WpfUICommon.AttachedProperties
{
[SupportedOSPlatform("windows")]
public class AutoRepositionPopupBehavior : Behavior<Popup>
{
    private const int WM_MOVING = 0x0216;

    // should be moved to a helper class
    private DependencyObject GetTopmostParent(DependencyObject element)
    {
        var current = element;
        var result = element;

        while (current != null)
        {
            result = current;
            current = (current is Visual || current is Visual3D) ?
               VisualTreeHelper.GetParent(current) :
               LogicalTreeHelper.GetParent(current);
        }
        return result;
    }

    protected override void OnAttached()
    {
        base.OnAttached();

        //AssociatedObject.LayoutUpdated += (sender, e) => Update();
        AssociatedObject.Loaded += (sender, e) =>
        {
            if (GetTopmostParent(AssociatedObject.PlacementTarget) is Window root)
            {
                var helper = new WindowInteropHelper(root);
                var hwndSource = HwndSource.FromHwnd(helper.Handle);
                if (hwndSource != null)
                {
                    hwndSource.AddHook(HwndMessageHook);
                }
            }
        };
    }

    private IntPtr HwndMessageHook(IntPtr hWnd,
            int msg, IntPtr wParam,
            IntPtr lParam, ref bool bHandled)
    {
        if (msg == WM_MOVING)
        {
            Update();
        }
        return IntPtr.Zero;
    }

    public void Update()
    {
        // force the popup to update it's position
        var mode = AssociatedObject.Placement;
        AssociatedObject.Placement = PlacementMode.Relative;
        AssociatedObject.Placement = mode;
    }
}
}

xaml中的用法:

xmlns:b="http://schemas.microsoft.com/xaml/behaviors" 
         xmlns:attachedprops="clr-namespace:YourBehaviourNameSpace"

 <Popup .... >
    <b:Interaction.Behaviors>                      
        <attachedprops:AutoRepositionPopupBehavior/>
    </b:Interaction.Behaviors>
</Popup>

相关问题