views:

18

answers:

1

Hello folks,

I have this code:

  <ComboBox Width="100" ItemsSource="{Binding FontList}" x:Name="fontComboFast">
                        <ComboBox.ItemsPanel>
                            <ItemsPanelTemplate>
                                <VirtualizingStackPanel />
                            </ItemsPanelTemplate>
                        </ComboBox.ItemsPanel>
                        <ComboBox.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding}" FontFamily="{Binding }" FontSize="12" />
                            </DataTemplate>
                        </ComboBox.ItemTemplate>
                    </ComboBox>

There are 3 gotchas in that Combobox.

  1. The Items/fonts have a different height
  2. When I scroll up/down the scrollviewer`s width increases/decreases depending on the Length of the longest visible item in the scrollviewer. How can I set a fixed width?
  3. The fonts aka TextBlocks are not vertically centered

How can I change those 3 things?

UPDATE:

 <ComboBox AlternationCount="2" Width="200"  ItemContainerStyle="{StaticResource alternateColor}" ItemsSource="{Binding Source={x:Static Member=Fonts.SystemFontFamilies}}" x:Name="fontComboFast">

<Style x:Key="alternateColor" TargetType="{x:Type ComboBoxItem}">
            <Style.Setters>
                <Setter Property="Height" Value="30" />
                <Setter Property="VerticalContentAlignment" Value="Center" />
                <Setter Property="FontSize" Value="16" />
            </Style.Setters>
            <Style.Triggers>                
                <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                    <Setter Property="Background" Value="LightGray"/>
                </Trigger>
                <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                    <Setter Property="Background" Value="AliceBlue"/>
                </Trigger>                
            </Style.Triggers>
        </Style>

Hm 2 of 3 answers were right and they were the easiest ones is this now a solution? :O You have some cool combobox tips in store? Then I would mark it as solution else you get a point ;-)

btw. congrats to your new wpf job read it on your blog, I envy you!

A: 
  1. Two options - a.) The not-so-pretty: set a fixed height in the TextBlock or b) put the items inside a Grid like this:

    <ComboBox ... Grid.IsSharedSizeScope="True">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.RowDefinistions>
                        <RowDefinition Height="Auto" SharedSizeGroup="Row"/>
                    <Grid.RowDefinistions>
                    <TextBlock .../>
                 <Grid>
             <DataTemplate>
         <ComboBox.ItemTemplate>
    
  2. Again - two options: a) Set a fixed width of the TextBlock in the DataTemplate. b) If you replace the VirtualizingStackPanel with a StackPanel and do the same for the ColumnDefinition above (this will be a performance problem if you have a lot in your list as it will create all visual elements when loading.

  3. Put VerticalAlignment="Center" in the TextBlock inside the DataTemlate.

Hope this helps.

EDIT:

Thanks :). I'll give you a few hints:

When using the VirtualizingStackPanel, in almost all cases you should set VirtualizationMode="Recycling" - same goes for the other ItemsControls by the way:

<ListBox VirtualizingStackPanel.VirtualiationMode="Recycling"/>
<VirtualizingStackPanel VirtualizationMode="Recycling"/>

This will recycle the DataTemplate's when the user scrolls through the list. Especially in large datasets or with complex DataTemplates this will give a considerable smoother experience. IsEditable="True" destroys this benefit (It's a known bug).

Normally when you only want to use one property as the DataTemplate, you can use the DisplayMemberPath - and this will give you keyboard accelerators (typing 'T' will scroll to the first item beginning with T etc.) If you use DataTemplates - you can achieve the same by using TextSearch.TextPath. Just remember to sort the items in the combobox to the same property that you use in the TextPath - otherwise, users are in for a 'bumpy' experience as it will seemingly randomly jump about the list.

If you want to color every second item in the list - you can achieve this as follows:

<UserControl.Resources>
    <Style TargetType="{x:Type ComboBoxItem}">
        <Style.Triggers>
            <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                <Setter Property="Background" Value="LightGray"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>
<ComboBox AlternationCount="2">

Actually, I don't really use the ComboBox that much - mostly, I use it for Enum-values and very small datasets. The problem with the ComboBox is that it supports paging very poorly - with large datasets I normally use the AutoCompleteBox from the WPF Toolkit or a ListBox with a TextBox above it for filtering.

Hope, you got a few hints in there :-)

Goblin
1b.worked NOT2a.worked3..worked
Lisa
I post an image here so you know what I mean and you see the misbehaviour: http://666kb.com/i/bm0et3s0n9atkmzol.png
Lisa
ok I got it see my update init post.
Lisa
haha... about the last hint, exactly that code I already posted shame on you! XDabout the keyboard accelerators typing T: I do not need to set DisplayMemberPath for that. Just IsEditable=True and enter a wished font and it works like autocomplete box etcabout the recycling: I can feel no difference in speed scrolling having 250 fonts in that combobox with your VirtualizationMode="Recycling" hint. And if you say now I should try it with 5000 fonts I think then a Combobox is anyway not suited for such an amount of data. Better overview would give a ListView.
Lisa
About your first answer with the Grid.ShareSizedScopeI bet you read it here: http://joshsmithonwpf.wordpress.com/2008/09/06/synchronizing-the-width-of-elements-in-an-itemscontrol/he found that trick 2 years ago I tried it and its unusable because even with only 250 fonts the scrolling slows heavily down.Well all together we need some improvements here, but its sunday you showed a bit motivation so you get the solution :P
Lisa
I need more coffee... :-) About the 250 fonts - if you have heavy datatemplates - you will notice it :) (I sometimes have very complex Grid-templates with graphics and all kinds of pizzaaas. :-)The problem with IsEditable is that it destroys the functionality of the VirtualizingStackPanel.
Goblin