【问题标题】:WPF ListBox fixed widthWPF ListBox 固定宽度
【发布时间】:2010-11-11 15:05:40
【问题描述】:

我在PopupControl 中有一个ListBox。问题是在滚动时,Popup 会调整大小 以适应实际最宽的元素。

如何避免这种调整大小并自动调整到整个列表中最宽的元素?

我尝试将其放入Grid,但没有成功。

【问题讨论】:

  • 您能否根据其内容计算特定 ListBoxItem 的宽度?

标签: wpf listbox width fixed


【解决方案1】:

好的,这是解决方案:添加此属性

<ListBox VirtualizingStackPanel.IsVirtualizing="False"

调整大小停止,因为现在 Panel 包含所有元素并且调整了宽度 尊重最广泛的。 使用虚拟化面板,它只是显示的项目的一部分,列表框将宽度调整为实际可见的最宽元素。

缺点是,我们不再使用Virtualizing Panel(默认开启)

【讨论】:

    【解决方案2】:

    如果您想继续进行虚拟化,可以将Popup.Width 设置为常量。

    当然,要选择正确的常数,您必须计算(或至少猜测)每个 ListBoxItem 的宽度,然后选择最大值。 ...通常根据您的内容,粗略猜测并不难。

    【讨论】:

      【解决方案3】:

      我遇到了与上述完全相同的问题 - 我的 ListBox 不会虚拟化,因为它会忙于在可调整大小的 PopUp 控件中进行布局。我找到的解决方案是限制包含ListBox 的网格的MaxWidthMaxHeight。我的PopUp 控件仍然可以通过 Grip 调整大小 - 它只是在它可以占用的空间中不是无限的 - 我认为一旦知道这可以解决问题,那就放弃一个简单的解决方案:-)

      我知道ListBox 正在虚拟化,因为包含大约 18,000 个元素的查询会在 1-2 秒而不是 30-60 秒内得到回答,并且滚动速度很快而不是冻结。

      <Popup x:Name="PART_Popup"
             AllowsTransparency="true"  
             PlacementTarget="{Binding ElementName=PART_ContentHost}"                                   
             Placement="Bottom"                                                        
             IsOpen="{Binding IsPopupOpened, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"                                     
             PopupAnimation="None"
             Focusable="False"
             StaysOpen="True"
          >
          <Border BorderBrush="{TemplateBinding PopupBorderBrush}"
                  BorderThickness="{TemplateBinding PopupBorderThickness}"
                  Background="{DynamicResource {x:Static reskeys:ResourceKeys.ControlPopupBackgroundBrushKey}}"  
                  >
              <!-- Do NOT REMOVE MaxHeight and MaxWidth
                   These ensure that containing ListBox is virtualizing -->
              <Grid x:Name="PART_ResizeableGrid" Background="Transparent"
                    MaxHeight="600"
                    MaxWidth="600"
                    >
                  <Grid.RowDefinitions>
                      <RowDefinition Height="*"/>
                  </Grid.RowDefinitions>
      
                  <Border
                      x:Name="DropDownBorder"
                      Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"  
                      Width="{Binding ActualWidth, ElementName=PART_ContentHost}"                                             
                      Height="{Binding ActualHeight, ElementName=PART_ContentHost}"
                      HorizontalAlignment="Stretch"
                      VerticalAlignment="Stretch"
                      Grid.RowSpan="2"
                      BorderThickness="0"
                      />
      
                  <ListBox
                      x:Name="PART_ItemList" Grid.Row="0"
                      HorizontalAlignment="Stretch" VerticalAlignment="Top"
                      ItemsSource="{Binding Suggestions, RelativeSource={RelativeSource TemplatedParent}}"
                      BorderThickness="0"
                      ItemTemplate="{TemplateBinding ItemTemplate}"
                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"                                                             
                      Template="{DynamicResource {x:Static reskeys:ResourceKeys.PopListBoxControlTemplate}}"
                      ScrollViewer.HorizontalScrollBarVisibility="Auto" 
                      ScrollViewer.VerticalScrollBarVisibility="Auto" 
                      ScrollViewer.CanContentScroll="True"
      
                      DisplayMemberPath="{TemplateBinding DisplayMemberPath}"
                      SelectedValuePath="{TemplateBinding ValuePath}"
      
                      KeyboardNavigation.AcceptsReturn="True"
                      KeyboardNavigation.DirectionalNavigation="Cycle"
      
                      BorderBrush="{TemplateBinding BorderBrush}"
                      VirtualizingPanel.IsVirtualizing="True"
                      VirtualizingPanel.VirtualizationMode="Recycling"
                      ScrollViewer.IsDeferredScrollingEnabled="True"
                      />
      
                  <!-- RezizeGrip Thumb to support resizing the suggestion lib -->
                  <Thumb x:Name="PART_ResizeGripThumb"
                         Grid.Row="0"
                         Style="{DynamicResource {x:Static reskeys:ResourceKeys.ResizeGripStyleKey}}"
                         HorizontalAlignment="Right"
                         VerticalAlignment="Bottom"
                         Margin="0"
                         Background="Transparent"
                         Width="16"
                         Height="16" />
              </Grid>
          </Border>
      </Popup>
      

      【讨论】:

        【解决方案4】:

        大多数 WPF UIElement 控件都有一个 Width 属性,可以将其设置为“Auto”,因此它们占用的空间与其最宽的元素一样多。

        【讨论】:

        • 我认为这在这种情况下是行不通的,因为如果打开虚拟化,没有任何东西可以确定最宽的元素是什么。
        猜你喜欢
        • 1970-01-01
        • 2014-04-08
        • 1970-01-01
        • 2013-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-12
        • 1970-01-01
        相关资源
        最近更新 更多