2009-06-12 9 views
3

J'ai besoin d'aide pour le problème suivant:Comment créer une propriété pour stocker l'index de la valeur sélectionnée à partir d'une autre propriété?

J'ai une classe avec deux propriétés.

private byte m_selectedValue; 
public byte SelectedValue 
{ 
    get { return m_selectedValue; } 
    set { m_selectedValue = value; } 
} 

private string[] m_possibleValues; 
public string[] PossibleValues 
{ 
    get { return m_possibleValues; } 
    set { m_possibleValues = value; } 
} 

La propriété Valeurs possibles stocke la liste des valeurs sélectionnables. SelectedValue contient l'index de la valeur sélectionnée.

Dans cet état, l'éditeur de propriétés affiche l'index de la valeur sélectionnée. Je voudrais sélectionner la valeur en utilisant une liste déroulante dans la grille de propriété, le même style utilisé avec une propriété Enum. La liste de la liste déroulante serait remplie à partir de la propriété PossibleValues.

Avec l'aide de cet article (http://www.codeproject.com/KB/cpp/UniversalDropdownEditor.aspx) J'ai réussi à créer un éditeur personnalisé qui affiche la liste déroulante sur la grille de propriété avec les valeurs de la propriété PossibleValues. Je peux également sélectionner la valeur, mais la grille de propriétés affiche toujours l'index de la valeur au lieu de la valeur elle-même.

C'est la source modifiée de l'éditeur (original est de CodeProject):

public class EnumParamValuesEditor : UITypeEditor 
{ 
    private IWindowsFormsEditorService edSvc; 

    public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context) 
    { 
     if ((context != null) && (context.Instance != null)) 
      return UITypeEditorEditStyle.DropDown; 
     return UITypeEditorEditStyle.None; 
    } 

    public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value) 
    { 
     if ((context == null) || (provider == null) || (context.Instance == null)) 
      return base.EditValue(provider, value); 
     edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)); 
     if (edSvc == null) 
      return base.EditValue(provider, value); 
     ListBox lst = new ListBox(); 
     PrepareListBox(lst, context); 
     lst.SelectedIndex = (byte)value; 
     edSvc.DropDownControl(lst); 
     if (lst.SelectedItem == null) 
      value = null; 
     else 
      value = (byte)lst.SelectedIndex; 
     return value; 
    } 

    private void PrepareListBox(ListBox lst, ITypeDescriptorContext context) 
    { 
     lst.IntegralHeight = true; 
     string[] coll = ((EnumTerminalParam)context.Instance).PossibleValues; 
     if (lst.ItemHeight > 0) 
     { 
      if ((coll != null) && (lst.Height/lst.ItemHeight < coll.Length)) 
      { 
       int adjHei = coll.Length * lst.ItemHeight; 
       if (adjHei > 200) 
        adjHei = 200; 
       lst.Height = adjHei; 
      } 
     } 
     else 
      lst.Height = 200; 
     lst.Sorted = true; 
     FillListBoxFromCollection(lst, coll); 
     lst.SelectedIndexChanged += new EventHandler(lst_SelectedIndexChanged); 
    } 

    void lst_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     if (edSvc == null) 
      return; 
     edSvc.CloseDropDown(); 
    } 

    public void FillListBoxFromCollection(ListBox lb, ICollection coll) 
    { 
     lb.BeginUpdate(); 
     lb.Items.Clear(); 
     foreach (object item in coll) 
      lb.Items.Add(item); 
     lb.EndUpdate(); 
     lb.Invalidate(); 
    } 

} 

Bien sûr, il a besoin d'autres modifications pour gérer correctement certaines situations (ex les PossibleValues ​​est vide.).

Est-il possible d'afficher les valeurs possibles [SelectedValue] au lieu de SelectedValue dans l'éditeur de propriétés?

Répondre

1

Vous devez attacher un TypeConverter personnalisé à votre propriété SelectedValue et rendre les valeurs possibles non consultables. TypeConverter sera responsable de l'affichage des chaînes dans le PropertyGrid au lieu des ints. Donc, fondamentalement, vous devez remplacer CanConvertFrom, CanConvertTo, ConvertFrom et ConvertTo. Lorsque vous souhaitez obtenir vos chaînes personnalisées, utilisez l'argument de contexte passé à ces méthodes et appelez votre propriété PossibleValues ​​dans votre instance cible. Cela devrait le faire. Apparemment, vous n'avez besoin d'aucun UITypeEditor personnalisé ici.

+0

Je pensais que GetStandardValuesSupported et GetStandardValues ​​étaient utilisés pour afficher une liste déroulante dans l'éditeur de propriétés. Malheureusement, GetStandardValues ​​doit retourner une collection avec des éléments du même type que la propriété elle-même, au moins selon http://msdn.microsoft.com/en-us/library/ayybcxe5.aspx. Comment puis-je rendre l'éditeur de propriété pour afficher la liste déroulante avec les méthodes ConvertFrom ou ConvertTo? – starobrno

+0

Oui, GetStandardValues ​​renvoie votre type natif (octet). Et c'est ce qui va déclencher une combobox. ConvertFrom et ConvertTo effectuent simplement les conversions vers/depuis vos chaînes personnalisées afin que les chaînes et non les octets soient affichés dans la liste. –

0

Au lieu de deux propriétés distinctes, pourquoi ne pas les lier ensemble dans un type de dictionnaire. Tellement plus facile à utiliser dans ce cas. Avec votre index comme clé et la chaîne [] comme valeurs. Ne vous limitez pas à un octet pour l'index.

+0

Si je change les valeurs possibles de la chaîne [] au dictionnaire , j'ai toujours besoin d'une propriété pour stocker la valeur actuellement sélectionnée. L'application traite les informations d'un périphérique externe et, après traitement, les informations sont renvoyées. J'utilise le type de données byte parce que ce périphérique n'accepte que les valeurs comprises entre 0 et 255. – starobrno

Questions connexes