2010-10-22 13 views
9

Uzun açıklamalara sahip öğelerin listesine bağlı bir WPF combobox'ım var.Bir WPF ComboBox'ta açılan liste değerleri/seçilen öğe için farklı bir değer nasıl görüntülenir?

ComboBox'a bağlı olan yazımın özellikleri olarak hem kısa hem de uzun açıklaması vardır. Şu anda, tam açıklamaya bağlanıyorum.

comboBox.DisplayMemberPath = "FullDescription"; 

nasıl öğesi seçilir ve combobox tek bir öğe olarak görüntülendiğinde, bu açılır FullDescription gösterecektir ise ShortDescription özelliğinin bir değer olarak gösterilecektir sağlamak için?

cevap

16

Güncelleme 2011-11-14

Geçenlerde yine aynı gereksinimi üzerine geldi ve ben aşağıda yayınlanmıştır çözümden çok memnun değildi. ComboBoxItem'u yeniden şablonlandırmadan aynı davranışı almanın daha güzel bir yolu. Düzenli DataTemplate, açılan DataTemplate ve ComboBox için kaynaklarda ComboBoxItemTemplateSelector belirtin bir DataTemplateSelector

İlk kullanır. Kap Eğer öyleyse, o zaman bir açılan öğe ile ilgileniyor, bir ComboBoxItem çocuğu ise Ardından aksi takdirde ComboBox yılında öğedir, ItemTemplateSelector

<ComboBox ... 
      ItemTemplateSelector="{DynamicResource itemTemplateSelector}"> 
    <ComboBox.Resources> 
     <DataTemplate x:Key="selectedTemplate"> 
      <TextBlock Text="{Binding Path=ShortDescription}"/> 
     </DataTemplate> 
     <DataTemplate x:Key="dropDownTemplate"> 
      <TextBlock Text="{Binding Path=FullDescription}"/> 
     </DataTemplate> 
     <local:ComboBoxItemTemplateSelector 
      x:Key="itemTemplateSelector" 
      SelectedTemplate="{StaticResource selectedTemplate}" 
      DropDownTemplate="{StaticResource dropDownTemplate}"/> 
    </ComboBox.Resources> 
</ComboBox> 

ComboBoxItemTemplateSelector kontroller için bir DynamicResource olarak ComboBoxItemTemplateSelector başvuru.

public class ComboBoxItemTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate DropDownTemplate 
    { 
     get; 
     set; 
    } 
    public DataTemplate SelectedTemplate 
    { 
     get; 
     set; 
    } 
    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     ComboBoxItem comboBoxItem = VisualTreeHelpers.GetVisualParent<ComboBoxItem>(container); 
     if (comboBoxItem != null) 
     { 
      return DropDownTemplate; 
     } 
     return SelectedTemplate; 
    } 
} 

GetVisualParent

public static T GetVisualParent<T>(object childObject) where T : Visual 
{ 
    DependencyObject child = childObject as DependencyObject; 
    while ((child != null) && !(child is T)) 
    { 
     child = VisualTreeHelper.GetParent(child); 
    } 
    return child as T; 
} 

Alt çözelti gerektirir ComboBoxItem

<SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" /> 
<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" /> 

<ControlTemplate x:Key="FullDescriptionTemplate" TargetType="ComboBoxItem"> 
    <Border Name="Border" Padding="2" SnapsToDevicePixels="true"> 
     <StackPanel> 
      <TextBlock Text="{Binding Path=FullDescription}"/> 
     </StackPanel> 
    </Border> 
    <ControlTemplate.Triggers> 
     <Trigger Property="IsHighlighted" Value="true"> 
      <Setter TargetName="Border" Property="Background" Value="{StaticResource SelectedBackgroundBrush}"/> 
     </Trigger> 
     <Trigger Property="IsEnabled" Value="false"> 
      <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/> 
     </Trigger> 
    </ControlTemplate.Triggers> 
</ControlTemplate> 

<ComboBox Name="c_comboBox" ItemsSource="{Binding}"> 
    <ComboBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Path=ShortDescription}"/> 
     </DataTemplate> 
    </ComboBox.ItemTemplate> 
    <ComboBox.ItemContainerStyle> 
     <Style TargetType="{x:Type ComboBoxItem}"> 
      <Setter Property="Template" Value="{StaticResource FullDescriptionTemplate}" /> 
     </Style> 
    </ComboBox.ItemContainerStyle> 
</ComboBox> 
Bu aşağıdaki davranışı ile sonuçlanır

yeniden şablon

alt text

+0

Teşekkür! WPF'deki her şey gibi ... her şey mümkün, fakat bazen XAML'de çok satır var :) – Marek

+2

[Bu yöntem] 'i gördünüz mü (http://stackoverflow.com/a/8279344/546730)? –

+0

seçili seçenek doğru şekilde gösterilmiyor. Bunun yerine tam nitelikli sınıf özellik adı gösterilir (yeni çözüme göre) –

0

Bulduğum başka bir seçenek, açılan kutunun metin alanına bir metin kutusu yerleştirmektir. o zaman bu bir alt benzer kullanmak mükemmel üzerinde bırakır ve böylece Boyut ve onu hizaya:

Private Sub ComboBox*_Change() 
Dim T As String 
T = Left(ComboBox*.Text, 1) 
TextBox*.Value = T 
End Sub 

(değiştirilmesi için ilgili sayılarla *) sonuç seçildiğinde açılan her zamanki gibi listesini görüntüler olmasıdır ancak üzerinde yatan metin kutusu sadece ilk karakterini gösterecektir.

Bu yardımcı olur umarım.

2

Artık benim için çalışmaya görünmüyor, ama bunu yapar:

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

    public override DataTemplate SelectTemplate(object item, DependencyObject container) { 
    var presenter = (ContentPresenter)container; 
    return (presenter.TemplatedParent is ComboBox) ? SelectedTemplate : DropDownTemplate; 
    } 
} 
İlgili konular