【问题标题】:how to make a wpf combobox popup Left如何使 wpf 组合框弹出左侧
【发布时间】:2016-11-07 01:55:02
【问题描述】:

我有一个组合框,其中的项目比实际组合框宽度宽,下拉菜单向右溢出。 我们如何使组合框弹出窗口溢出左侧而不是右侧。

FlowDirection 不这样做。

建议的线程中建议的解决方案将使组合框的箭头位于左侧。我需要它保持在右侧。

<ComboBox.Style>
        <Style TargetType="ComboBox" >                                    
            <Setter Property="Popup.FlowDirection" Value="RightToLeft"/>                  
        </Style>
    </ComboBox.Style>  

【问题讨论】:

  • 这个帖子可能有帮助:stackoverflow.com/questions/5340640/…
  • 我在搜索时遇到了这个帖子,但它没有达到我想要的效果。
  • 说我提出的解决方案没有改变行为有点误导。它确实满足了您的初始要求(将 FlowDirection 从 LTR 更改为 RTL)。如果您希望箭头位于右侧,我建议您考虑更改渲染模板或根据新要求打开一个新线程问题。也不要通过添加 cmets...
  • geostoker:如果您阅读了推荐的解决方案(线程),它会在右侧显示箭头,但实际上是在左侧。不要将 cmets 用于个人。保持专业!
  • 我完全没有个人看法,但正如我多次被告知的那样,不断向问题添加要求并不是一种好的 SO 格式。 OT:没有图片或提及箭头位于线程的相反(右侧)。但是,根据 cmets,如果您有双显示器,则 popup.placement 存在一个已知问题。如前所述,看看如何操作渲染器(这在其他线程中有所提及)。 :)

标签: wpf combobox popup


【解决方案1】:

我建议您扩展标准的ComboBox 控件以操作其Popup 控件。在我看来,这是解决您的问题的最简单、最快的解决方案。

public class LeftComboBox : ComboBox
{
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        Popup popup = GetTemplateChild("PART_Popup") as Popup;
        popup.Placement = PlacementMode.Custom;
        popup.CustomPopupPlacementCallback = new CustomPopupPlacementCallback(CustomPopupPlacementCallback);
    }

    private static CustomPopupPlacement[] CustomPopupPlacementCallback(Size popupSize,
        Size targetSize, Point offset)
    {
        Point point = new Point(targetSize.Width - popupSize.Width, targetSize.Height);

        List<CustomPopupPlacement> customPopupPlacement =
            new List<CustomPopupPlacement>();

        customPopupPlacement.Add(new CustomPopupPlacement(point, PopupPrimaryAxis.Vertical));

        return customPopupPlacement.ToArray();
    }
}

通过扩展标准ComboBox 控件,您可以覆盖OnApplyTemplate,并且可以强制其Popup 使用自定义PlacementMode

然后您可以编写自己的CustomPopupPlacementCallback。我的只是改变了Popup 的水平偏移,向左移动。

希望对你有帮助。

【讨论】:

    【解决方案2】:

    我建议使用 Behavior 来执行此操作。我正在添加带有 MenuItem 的示例,但对于任何带有 PopUp 的控件(如 ComboBox)都是相同的

    在您的 Xaml 上,将附加行为添加到菜单项:

          <Menu>
                <MenuItem ItemsSource="{Binding GlanceOptions, Mode=OneWay}">
    
                    <interactivity:Interaction.Behaviors>
                        <behaviors:MenueItemSubMenuPlacementBehavior />
                    </interactivity:Interaction.Behaviors>
    
                    <MenuItem.Header>
                        <Border                    
                            Cursor="Arrow"
                            BorderThickness="1,1,1,0" >
                            <Path x:Name="DropDownIcon"
                                            VerticalAlignment="Center"
                                            Data="M0,0L2,3 4,0z"
                                            />
                        </Border>
                    </MenuItem.Header>
                </MenuItem >
            </Menu>           
    

    行为代码:

            public class MenueItemSubMenuPlacementBehavior : Behavior<MenuItem>
            {
                private PlacementMode _previousPlacementMode;
                private CustomPopupPlacementCallback _previousCallback;
                private Popup _menuItemPopUp;
    
                protected override void OnAttached()
                {
                    base.OnAttached();
    
                    Initialize();
                }
    
                private void Initialize()
                {
                    if (AssociatedObject == null)
                        return;
    
                    if (_menuItemPopUp == null)
                    {
                        _menuItemPopUp = AssociatedObject?.Template?.FindName("PART_Popup", AssociatedObject) as Popup;
    
                        if (_menuItemPopUp == null)
                        {
                            AssociatedObject.Loaded -= AssociatedObject_Loaded;
                            AssociatedObject.Loaded += AssociatedObject_Loaded;
                            return;
                        }
    
                        _previousPlacementMode = _menuItemPopUp.Placement;
                        _previousCallback = _menuItemPopUp.CustomPopupPlacementCallback;
    
                        _menuItemPopUp.Placement = PlacementMode.Custom;
                        _menuItemPopUp.CustomPopupPlacementCallback = CustomPopupPlacementCallback;
                    }
                }
    
                private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
                {
                    AssociatedObject.Loaded -= AssociatedObject_Loaded;
    
                    if (_menuItemPopUp != null)
                        return;
    
                    _menuItemPopUp = VisualTreeHelpers.FindFirstChild<Popup>(AssociatedObject) as Popup;
    
                    if (_menuItemPopUp == null)
                        return;
    
                    _previousPlacementMode = _menuItemPopUp.Placement;
                    _previousCallback = _menuItemPopUp.CustomPopupPlacementCallback;
    
                    _menuItemPopUp.Placement = PlacementMode.Custom;
                    _menuItemPopUp.CustomPopupPlacementCallback = CustomPopupPlacementCallback;
                }
    
                protected override void OnDetaching()
                {
                    base.OnDetaching();
    
                    if(AssociatedObject != null)
                    {
                        AssociatedObject.Loaded -= AssociatedObject_Loaded;
                    }
    
                    if (_menuItemPopUp != null)
                    {
                        _menuItemPopUp.Placement = _previousPlacementMode;
                        _menuItemPopUp.CustomPopupPlacementCallback = _previousCallback;
    
                        _previousCallback = null;
                    }
                }
    
                private CustomPopupPlacement[] CustomPopupPlacementCallback(Size popupSize, Size targetSize, Point offset)
                {
                    var rightPlacedPopupX = offset.X;
                    var rightPlacedPopupY = offset.Y + (AssociatedObject.ActualHeight * YourLogic);
    
                    return new[]
                    {
                        new CustomPopupPlacement(new Point(rightPlacedPopupX, rightPlacedPopupY), PopupPrimaryAxis.Horizontal),
                    };
                }
            }
    

    【讨论】:

      猜你喜欢
      • 2021-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-16
      • 2021-10-04
      • 1970-01-01
      • 2013-07-02
      • 2013-08-02
      相关资源
      最近更新 更多