2009-02-11 18 views
22

Dört değerlerle Bir enum var demek:XAML'deki bir WPF açılır kutuyu belirli bir enumdaki tüm öğelerle nasıl doldurabilirim?

XAML Bu öğelerle doldurulur bir ComboBox sahip gerekecektir hangi
public enum CompassHeading 
{ 
    North, 
    South, 
    East, 
    West 
} 

?

<ComboBox ItemsSource="{Binding WhatGoesHere???}" /> 

Bunun için C# kodunu ayarlamak zorunda kalmazdım.

+0

Sadece Eric Burke'ün bunu yapan bir Swing JComboBox sınıfı hakkındaki son yazısını okudum ve "Hey, yemin ederim ki bu konuda çok soru gördüm ..." diye düşündüm. Yakındım ama WPF'yi değil, Java/Swing'i istiyorsun . Her neyse, işte burada kâhya için: http://stuffthathappens.com/blog/2009/02/10/a-swing-jcombobox-for-enums/ – JMD

cevap

23

Bunu yapmak için ObjectDataProvider kullanabilirsiniz:

http://bea.stollnitz.com/blog/?p=28

+0

Teşekkürler, bu çözüm de TwoWay ciltleme ile iyi çalışıyor gibi görünüyor. IsSynchronizedWithCurrentItem = "true" ifadesinin bu soru için kırmızı bir ringa balığı olduğunu unutmayın (bunu diğer ziyaretçiler için netleştirmek amacıyla kaldırmak isteyebilirsiniz). –

+1

Bu, yerelleştirmeyi desteklemiyor. – Guge

+1

@Guge: Hayır, yok, ancak numaralandırma yerelleştirmeyi de desteklemiyor. Her bir yerellik için farklı bir numaralandırma oluşturmanız gerekir veya sizin için yerelleştirme değerlerini oluşturabilecek bir özellik eklemeniz gerekir (bu, bir tür anahtarlanmış bir arama kullanır), bu durumda, soru ve cevap yok ' Artık başvurmak. – casperOne

6

Here WPF

yılında çeteleler nasıl bağlamak ayrıntılı bir örnektir: Burada çözüm buldu
<ObjectDataProvider MethodName="GetValues" 
    ObjectType="{x:Type sys:Enum}" x:Key="odp"> 
    <ObjectDataProvider.MethodParameters> 
     <x:Type TypeName="local:CompassHeading"/> 
    </ObjectDataProvider.MethodParameters> 
</ObjectDataProvider> 

<ComboBox ItemsSource="{Binding Source={StaticResource odp}}" /> 

aşağıdaki enum sahip varsayalım

public enum EmployeeType  
{ 
    Manager, 
    Worker 
} 

Daha sonra da kontrol codebehind

typeComboBox.ItemsSource = Enum.GetValues(typeof(EmployeeType)); 

yılında bağlamak veya ObjectDataProvider

<ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="sysEnum"> 
    <ObjectDataProvider.MethodParameters> 
     <x:Type TypeName="local:EmployeeType" /> 
    </ObjectDataProvider.MethodParameters> 
</ObjectDataProvider> 

kullanmak ve şimdi biçimlendirme

<ComboBox ItemsSource="{Binding Source={StaticResource sysEnum}}" /> 

bağladığına edebilirsiniz: Databinding an enum property to a ComboBox in WPF

1

Üçüncü bir çözüm:

Bu, biraz daha fazla çalışma önündedir, Enums yüklerini bağlarsanız uzun vadede daha kolay olur. Numaralama türünü bir parametre olarak alan bir Dönüştürücü kullanın ve bunu bir çıkış dizisi olarak bir dizi dizeye dönüştürür. VB.NET içinde

:

Public Class EnumToNamesConverter 
    Implements IValueConverter 

    Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert 
     Return [Enum].GetNames(DirectCast(value, Type)) 
    End Function 

    Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack 
     Throw New NotImplementedException() 
    End Function 
End Class 

Veya C#

:

<local:EnumToNamesConverter x:Key="EnumToNamesConverter" /> 

Son olarak kullanın: senin Application.xaml yılında Sonra

public sealed class EnumToNamesConverter : IValueConverter 
{ 
    object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
    return Enum.GetNames(value.GetType()); 
    } 

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
    throw New NotSupportedException() 
    } 
} 

, bu dönüştürücü erişmek için global bir kaynak eklemek Herhangi bir XAML sayfasındaki herhangi bir Enum ...

The Missing .NET #7: Displaying Enums in WPF

Bu makale de belli değerlerin sunumunu ağır basan bir yöntem gösterilmektedir: tekniğinin alternatifleri ve sözcükler bir adım-adım örneklerde için

<ComboBox ItemsSource="{Binding 
         Source={x:Type local:CompassHeading}, 
         Converter={StaticResource EnumToNamesConverter}}" /> 
+0

Merhaba maranite2, Bu çözümün görünüşünü beğendim ama TwoWay ciltleme ile çalışamadım.Bağlama, denetimden verilere (kaydederken) çalışır, ancak veriyi denetlemek için çalışmaz (açılan kutu başlangıçta seçili bir değer olması gereken yerde boştur). –

3

, bu web sayfasını deneyin . Kod örnekleri bol iyi bir okuma.Bunun gerçekten sıkıcı yapmak için bir ObjectDataProvider kullanarak düşünüyorum

14

... Bir daha özlü önerimiz var bir biçimlendirme uzantısını kullanarak, (biliyorum evet, biraz ... Geç):

<ComboBox ItemsSource="{local:EnumValues local:EmployeeType}"/> 

İşte biçimlendirme uzantısı kodu şöyledir:

[MarkupExtensionReturnType(typeof(object[]))] 
public class EnumValuesExtension : MarkupExtension 
{ 
    public EnumValuesExtension() 
    { 
    } 

    public EnumValuesExtension(Type enumType) 
    { 
     this.EnumType = enumType; 
    } 

    [ConstructorArgument("enumType")] 
    public Type EnumType { get; set; } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     if (this.EnumType == null) 
      throw new ArgumentException("The enum type is not set"); 
     return Enum.GetValues(this.EnumType); 
    } 
} 
+0

Seninkini görene kadar seninkine yakın bir sınıf buldum. Mine, return ifadesinden önce bir tane daha check: 'enumType.IsEnum' ekler. –

3

Bu kilisede küfür gibi olabilir, ama ben aşağıdaki nedenlerle XAML açıkça her ComboBoxItem ilan etmek isteriz:

  • Yerelleştirmeye ihtiyacım varsa, XAML'a bir çevirmene verebilir ve kodu kendim için saklayabilirim.
  • Belirli bir ComboBox için uygun olmayan enum değerlerim varsa, bunları göstermek zorunda değilim.
  • Enemlerin sırası, mutlaka kodda değil, XAML'de belirlenir.
  • Seçebileceğiniz enum değeri sayısı genellikle çok yüksek değil. Enums'ın yüzlerce değeri bir kod kokusuyla ele alacağını düşünürdüm.
  • Bazı ComboBoxItems öğelerinde grafiklere veya başka bir desteğe gereksinim duyarsam, bazı zor Şablon/Trigger öğeleri yerine ait olduğu XAML içine koymanız en kolay olurdu.
  • Aptal Basit

C# örnek kodu Keep It:

public enum number { one, two, three }; 

public partial class MainWindow : Window, INotifyPropertyChanged 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     this.DataContext = this; 
    } 

    private number _number = number.one; 
    public number Number 
    { 
     get { return _number; } 
     set { 
      if (_number == value) 
       return; 
      _number = value; 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs("Number")); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

XAML kodu: Gördüğünüz gibi

<Window x:Class="WpfApplication6.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="480" Width="677"> 
<Grid> 
    <ComboBox SelectedValue="{Binding Number}" SelectedValuePath="Tag"> 
     <ComboBoxItem Content="En" Tag="One"/> 
     <ComboBoxItem Content="To" Tag="Two"/> 
     <ComboBoxItem Content="Tre" Tag="Three"/> 
    </ComboBox> 
</Grid> 

, XAML lokalize edilmiş Norveççe, C# kodunda herhangi bir değişiklik yapılmasına gerek yoktur.

+1

Ve kutudan tasarım zamanı desteği alırsınız – surfen

İlgili konular