2011-11-26 53 views
13

我有一個ComboBox有相當複雜的模板個別項目,其中包括兩個圖像和幾行文字:不同的模板在組合框的下拉列表中的項目和所選項目

enter image description here

然而, ComboBox本身中的選定項目無法正確顯示,因爲垂直空間太有限(我無法將其更高,因爲它是ToolBar的一部分)。

如何使組合框爲ComboBox本身顯示的項目使用不同的模板?(默認ToString表示法就可以了)

謝謝!

+0

是使用DataTemplateSelector會做的伎倆,爲您或您正在尋找一個其他soluion?也許我沒有得到正確的答案? – sll

+0

@sll我不認爲DataTemplateSelector可以做到這一點(儘管我沒有嘗試),IIRC它只在項目被加載時才被評估。無論如何,我寧願一些簡單的解決方案,不會涉及我創建的每個組合框的類(將有幾個)。 –

+0

好的你想達到什麼目的?基於某些條件的項目的不同UI表示? – sll

回答

27

選擇的項目(在ComboBox本身,而不是下拉)不是ComboBoxItem裏面,所以你可以做這樣的事情:

<ComboBox.ItemTemplate> 
    <DataTemplate> 
     <ContentControl Content="{Binding}"> 
      <ContentControl.Style> 
       <Style TargetType="{x:Type ContentControl}"> 
        <!-- Complex default template --> 
        <Setter Property="ContentTemplate"> 
         <Setter.Value> 
          <DataTemplate> 
           <Image Source="{Binding XPath=media:thumbnail/@url}" Width="100" Height="100" /> 
          </DataTemplate> 
         </Setter.Value> 
        </Setter> 
        <Style.Triggers> 
         <!-- Simple selection box template --> 
         <DataTrigger 
           Binding="{Binding RelativeSource={RelativeSource AncestorType=ComboBoxItem}}" 
           Value="{x:Null}"> 
          <Setter Property="ContentTemplate"> 
           <Setter.Value> 
            <DataTemplate> 
             <TextBlock Text="{Binding XPath=title}" /> 
            </DataTemplate> 
           </Setter.Value> 
          </Setter> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </ContentControl.Style> 
     </ContentControl> 
    </DataTemplate> 
</ComboBox.ItemTemplate> 

編輯:注意,在爲綁定選擇框會拋出錯誤,因爲沒有找到RelativeSource。有多種選擇可以規避這種情況,一種是自定義值轉換器,根據祖先是否存在(手動樹行走)返回truefalse。)

+0

謝謝,工作很棒! –

+0

不客氣,很高興幫助:) –

+0

太棒了!謝謝! Ymmd :) – pr0gg3r

5

我正在尋找一個標準(不是hacky而且沒有綁定錯誤)解決這個問題。我發現它here:使用DataTemplateSelector

這與@H.B. answer的想法是一樣的:每當有一個ComboBoxItem作爲視覺樹中的父項時檢查。

public class ComboBoxItemTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate SelectedTemplate { get; set; } 
    public DataTemplate DropDownTemplate { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     while (container != null) 
     { 
      container = VisualTreeHelper.GetParent(container); 
      if (container is ComboBoxItem) 
       return DropDownTemplate; 
     } 
     return SelectedTemplate; 
    } 
} 

用法:

<ComboBox.ItemTemplateSelector> 
    <local:ComboBoxItemTemplateSelector> 
     <local:ComboBoxItemTemplateSelector.SelectedTemplate> 
      <DataTemplate> 
       ... simple template for selected item 
      </DataTemplate> 
     </local:ComboBoxItemTemplateSelector.SelectedTemplate> 
     <local:ComboBoxItemTemplateSelector.DropDownTemplate> 
      <DataTemplate> 
       ... complex template used by dropdown items 
      </DataTemplate> 
     </local:ComboBoxItemTemplateSelector.DropDownTemplate> 
    </local:ComboBoxItemTemplateSelector> 
</ComboBox.ItemTemplateSelector> 
相關問題