2016-07-13 5 views
1

У меня есть поле со списком с более широкими полями, чем фактическая ширина поля со списком, выпадающие пропуски вправо. Как мы можем создать всплывающее окно со списком слева, а не правую.как сделать всплывающее окно wpf combobox Left

FlowDirection этого не делает.

Решение, предложенное в рекомендуемой нити, сделает стрелку комбинированного блока слева. Мне нужно, чтобы он остался справа.

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

Эта нить может помочь: http://stackoverflow.com/questions/5340640/wpf-combobox-popup-placement-bottom-and-aligned-to-the-right -edge – geostocker

+0

Я наткнулся на эту тему, когда искал, но не добился того, что искал. – TheOne

+0

Любые идеи парней? – TheOne

ответ

2

Я предлагаю вам расширить стандартный 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, перемещая его влево.

Надеюсь, это может вам помочь.

0

Я предлагаю сделать это с Behavior.I'm добавив пример с 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), 
       }; 
      } 
     } 
Смежные вопросы