【问题标题】:How to align combobox popup to bottom Left wpf?如何将组合框弹出窗口与左下 wpf 对齐?
【发布时间】:2021-07-17 09:06:20
【问题描述】:

目标: 将组合框弹出窗口与左下角对齐。请查看下面的图片以供参考:

我尝试了什么?我尝试使用 PART_Popup 的 Placement 属性。如果我设置 Placement="Bottom",则弹出窗口将从右下角呈现。看看下面这张图片:

另外,在 VS Designer 中显示正确:

组合框 PART_Popup:

<Popup x:Name="PART_Popup"
       AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom"
       MinWidth="170">
    <themes:SystemDropShadowChrome x:Name="shadow" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}">
        <Border x:Name="dropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{StaticResource ComboBox.Static.Background}"
                CornerRadius="3">
            <ScrollViewer x:Name="DropDownScrollViewer" CanContentScroll="False">
                <Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
                    <Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
                        <Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}"
Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
                    </Canvas>
                    <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                    Margin="16"/>
                </Grid>
            </ScrollViewer>
        </Border>
    </themes:SystemDropShadowChrome>
</Popup>

XAML:

<ComboBox
HorizontalAlignment="Left" 
VerticalAlignment="Center" 
SelectedIndex="0"
Margin="50,0"
Style="{StaticResource FlatComboBoxStyle2}">
    <ComboBoxItem Content="Recent"/>
    <ComboBoxItem Content="Alphabetical"/>
</ComboBox>

我只在寻找 XAML 代码解决方案。谢谢。

【问题讨论】:

    标签: c# wpf xaml combobox


    【解决方案1】:

    我通过在 App.xaml.cs 中添加转换器来修复它:

        public class PositiveToNegativeConverter:IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return (double) value > 0 ? 0 - (double) value : 0;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    

    并在我的 ComboBoxTemplate 中定义它:

    <PositiveToNegativeConverter x:Key="PositiveToNegativeConverter" />
    

    并在 Popup 的 Horizo​​ntalOffest 中这样称呼它:

    HorizontalOffset="{Binding ActualWidth, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource PositiveToNegativeConverter}}" 
    

    我希望这对寻找解决方案的人有所帮助。

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,并且在这里关注了几个线程之后(我的所有 XAML 试验都失败了,简而言之,Popup.Placement = [whatever] 在运行时没有改变任何东西)我最终得到了以下“解决方案” .

      不漂亮,所以如果你知道我开放的更优雅的方式。

      所以我命名了我的 ComboBox 并在 DropDownOpen 上添加了一个事件处理程序(通过 XAML)(这是 imo 的脏端),我将 Popup.Placement 强制设置为 RelativePoint 并将 VerticalOffset 设置为我的 ComboBox.ActualHeight。

      这是 XAML 代码:

      <ComboBox Name="NIC_CmbBox" HorizontalAlignment="Stretch" DropDownOpened="NIC_CmbBox_DropDownOpened">                    
      

      C#:

      private Popup _comboBoxPopup;
      
      private void NIC_CmbBox_DropDownOpened(object sender, EventArgs e)
      {
          ComboPopupPlacement();
      }
      
      public Popup ComboBoxPopup {
          get
          {
              if(_comboBoxPopup == null)
              {
                  //try to get it
                  if(NIC_CmbBox != null)
                      _comboBoxPopup = (Popup)NIC_CmbBox.Template.FindName("PART_Popup", NIC_CmbBox);
              }
              return _comboBoxPopup;
          }
          set => _comboBoxPopup = value; }
      
      public void ComboPopupPlacement()
      {            
          //If placement haven't already be done
          if (ComboBoxPopup != null && _comboBoxPopup.Placement != PlacementMode.RelativePoint)
          {
              _comboBoxPopup.Placement = PlacementMode.RelativePoint;
              _comboBoxPopup.VerticalOffset = NIC_CmbBox.ActualHeight;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-30
        • 2012-04-24
        • 2016-04-03
        相关资源
        最近更新 更多