[c#] Associazione dati WPF: come associare i dati a una casella combinata utilizzando XAML?


Answers

Il modo in cui l'ho sempre fatto è il seguente. La bellezza di questa soluzione è che è completamente generica e può essere riutilizzata per qualsiasi tipo di enumerazione.

1) Quando si definisce un'enumerazione, utilizzare alcuni attributi personalizzati per fornire alcune informazioni. In questo esempio ho usato Browsable (false) per indicare che questo enumeratore è interno e non voglio vedere questa opzione in una casella combinata. Descrizione ("") mi consente di specificare un nome visualizzato per l'enumerazione.

public enum MyEnumerationTypeEnum
  {
    [Browsable(false)]
    Undefined,
    [Description("Item 1")]
    Item1,
    [Description("Item 2")]
    Item2,
    Item3
  }

2) Definire una classe che ho chiamato EnumerationManager. Questa è una classe generica che analizza un tipo di Enumerazione e genera un elenco di valori. Se un enumeratore ha Browsable impostato su false, verrà saltato. Se ha un attributo Description, utilizzerà la stringa descrittiva come nome visualizzato. Se non viene trovata alcuna descrizione, mostrerà solo la stringa predefinita dell'enumeratore.

public class EnumerationManager
  {
    public static Array GetValues(Type enumeration)
    {
      Array wArray = Enum.GetValues(enumeration);
      ArrayList wFinalArray = new ArrayList();
      foreach(Enum wValue in wArray)
      {
        FieldInfo fi = enumeration.GetField(wValue.ToString());
        if(null != fi)
        {
          BrowsableAttribute[] wBrowsableAttributes = fi.GetCustomAttributes(typeof(BrowsableAttribute),true) as BrowsableAttribute[];
          if(wBrowsableAttributes.Length > 0)
          {
            //  If the Browsable attribute is false
            if(wBrowsableAttributes[0].Browsable == false)
            {
              // Do not add the enumeration to the list.
              continue;
            }        
          }

          DescriptionAttribute[] wDescriptions = fi.GetCustomAttributes(typeof(DescriptionAttribute),true) as DescriptionAttribute[];
      if(wDescriptions.Length > 0)
      {
        wFinalArray.Add(wDescriptions[0].Description);
      }
      else 
        wFinalArray.Add(wValue);
        }
      }

      return wFinalArray.ToArray();
    }
  }

3) Nel tuo xaml aggiungi una sezione nel tuo ResourceDictionary

  <ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type l:EnumerationManager}" x:Key="OutputListForMyComboBox">
      <ObjectDataProvider.MethodParameters>
           <x:Type TypeName="l:MyEnumerationTypeEnum" />
      </ObjectDataProvider.MethodParameters>
  </ObjectDataProvider>

4) Collega ora l'elemento ItemsSource della tua casella combinata a questa chiave che abbiamo appena definito nel dizionario delle risorse

<ComboBox Name="comboBox2" 
          ItemsSource="{Binding Source={StaticResource OutputListForMyComboBox}}" />

Se provi questo codice usando la mia enumerazione sopra, dovresti vedere 3 elementi nella tua casella combinata:

Item 1
Item 2
Item3

Spero che questo ti aiuti.

EDITS: se si aggiunge l'implementazione di LocalizableDescriptionAttribute e si utilizza l'attributo Description che stavo usando sarebbe perfetto.

Question

Questa domanda ha già una risposta qui:

Ho una lezione:

public class AccountDetail
{
    public DetailScope Scope
    {
        get { return scope; }
        set { scope = value; }
    }

    public string Value
    {
        get { return this.value; }
        set { this.value = value; }
    }

    private DetailScope scope;
    private string value;

    public AccountDetail(DetailScope scope, string value)
    {
        this.scope = scope;
        this.value = value;
    }
}

e un enum:

public enum DetailScope
{
    Private, 
    Business, 
    OtherDetail
}

Infine, ho un file .xaml:

<Window x:Class="Gui.Wpf.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Test" 
    SizeToContent="WidthAndHeight">

    <Grid>
        <ComboBox 
            Name="ScopeComboBox" 
            Width="120" 
            Height="23" 
            Margin="12" />
    </Grid>
</Window>

Mi piacerebbe fare due cose:

  1. Desidero legare i valori di DetailsScope DetailsScope ai valori della casella combinata. Non desidero collegare direttamente i valori enum perché l'ultimo valore enum sarebbe OtherDetail invece di Other detail (aggiunto un carattere spazio e una piccola lettera 'd').
  2. Desidero associare i dati del valore selezionato nella casella combinata a quello specificato nell'istanza dell'oggetto AccountDetail .

Puoi aiutarmi? Grazie.

Aggiornamento: ho trovato questo post http://blogs.msdn.com/b/wpfsdk/archive/2007/02/22/displaying-enum-values-using-data-binding.aspx . Ho bisogno di qualcosa di simile.




Vorrei usare un convertitore di valori per questo, questo ti permetterà di legare direttamente usando il convertitore, puoi cambiare l'implementazione di Converti per creare una presentazione "più bella" leggibile dall'uomo dell'enumerazione, cioè divisa in caratteri maiuscoli.

C'è un articolo completo su questo approccio here .

  public class MyEnumToStringConverter : IValueConverter
  {
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
     {
         return value.ToString();
     }

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
     {
         return (MyEnum) Enum.Parse( typeof ( MyEnum ), value.ToString(), true );
     }
  }






Links