-1

ComboBox可能有很多項目。Combobox顯示和隱藏WPF中的ComboBox項目

這是該方案我想實現:

我要創建具有「更多」按鈕,位於最後ComboBox項目的定製ComboBox。如果ComboBox包含20個項目,則最初在單擊ComboBox並顯示下拉列表時,僅顯示10個項目,並顯示第10個項目下的「更多」按鈕。

只要點擊「更多」按鈕項目,「更多」按鈕將變成「更少」,下拉列表將顯示總共20個項目。所以當點擊「Less」按鈕時,顯示項目將被反轉回10個項目,另外10個項目將被隱藏。

10個初始顯示項目僅僅是一個例子。實際上,ComboBox's初始顯示項目的總數可以通過屬性設置。

例如:<local:CustomComboBox x:Name="CustomComboBox" InitialDisplayItem="10" />

我是新來WPF ...我怎麼能做到這一點?

回答

2

創建一個自定義的控制,如:

public class CrazyCombo : ComboBox 
{ 
    static CrazyCombo() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(CrazyCombo), new FrameworkPropertyMetadata(typeof(CrazyCombo))); 
    } 

    public int InitialDisplayItem 
    { 
     get { return (int)GetValue(InitialDisplayItemProperty); } 
     set { SetValue(InitialDisplayItemProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for InitialDisplayItem. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty InitialDisplayItemProperty = 
     DependencyProperty.Register("InitialDisplayItem", typeof(int), typeof(CrazyCombo), new UIPropertyMetadata(0)); 

    public override void OnApplyTemplate() 
    { 
     base.OnApplyTemplate(); 

     var moreLessButton = Template.FindName("moreLessButton", this) as Button; 

     moreLessButton.Click += new RoutedEventHandler(moreLessButton_Click); 
    } 

    void moreLessButton_Click(object sender, RoutedEventArgs e) 
    { 
     var moreLessButton = Template.FindName("moreLessButton", this) as Button; 

     if (moreLessButton.Content.ToString() == "More") 
     { 
      var icv = CollectionViewSource.GetDefaultView(Items); 

      icv.Filter = null; 
      moreLessButton.Content = "Less"; 
     } 
     else 
     { 
      var icv = CollectionViewSource.GetDefaultView(Items); 

      icv.Filter += o => Items.OfType<object>().Take(InitialDisplayItem).Contains(o); 

      moreLessButton.Content = "More"; 
     } 
    } 

    protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue) 
    { 
     base.OnItemsSourceChanged(oldValue, newValue); 

     var icv = CollectionViewSource.GetDefaultView(Items); 

     icv.Filter += o => Items.OfType<object>().Take(InitialDisplayItem).Contains(o); 
    } 

} 

在你需要把整個風格爲標準組合框的generic.xaml,您可以使用混合得到它。我不會發布它,因爲它是huuuuuggge。您將需要更改以下部分:

樣式更改爲指向您的自定義控制即

<Style TargetType="{x:Type local:CrazyCombo}"> 

在組合框彈出添加更多/更少按鈕

<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom"> 
         <Microsoft_Windows_Themes:SystemDropShadowChrome x:Name="Shdw" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=MainGrid}"> 
          <Border x:Name="DropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"> 
           <StackPanel> 
            <ScrollViewer x:Name="DropDownScrollViewer"> 
             <Grid RenderOptions.ClearTypeHint="Enabled"> 
              <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}"/> 
             </Grid> 
            </ScrollViewer> 
            <Button Name="moreLessButton" Content="More"/> 
           </StackPanel> 
          </Border> 
         </Microsoft_Windows_Themes:SystemDropShadowChrome> 
        </Popup> 

唯一除了標準的組合框控制模板是線

<Button Name="moreLessButton" Content="More"/> 

然後你瑟像

<Window x:Class="WpfApplication4.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication4" 
    Title="MainWindow" Height="350" Width="525" Foreground="red"> 

<StackPanel> 

    <local:CrazyCombo x:Name="bah" ItemsSource="{Binding Foo}" InitialDisplayItem="1"/> 

</StackPanel> 

如果你這樣做了真實的你一定會添加觸發器按鈕所以只如果有多個項目,則「InitialDisplayItem」顯示自定義控制。你可能也會使按鈕成爲切換按鈕而不是我愚蠢的切換代碼。

+0

謝謝!我會嘗試讓你知道! :) – DEN 2012-07-27 05:51:55

+0

非常感謝你!解決方案像魅力一樣工作! – DEN 2012-07-27 06:23:59

+0

不錯的工作人,愛的InitialDisplayItem dep道具。 – knockando 2012-11-26 17:54:24