Je deviens fou de liaison d'une zone de liste déroulante à une propriété typée enum d'une classe, où l'énumération elle-même est déclarée dans cette même classe.Liaison d'une zone de liste déroulante à une énumération imbriquée dans une classe
J'essaie de suivre la réponse fournie ici (wpf combobox binding to enum what i did wrong?) Spécifiquement j'utilise le code MarkupExtension suggéré et le code xaml correspondant.
Mon code de travail est:
Définition du Enum dans un fichier séparé.
namespace EnumTest
{
public enum TestEnum {one, two, three, four };
}
classe qui utilise le Enum (Notez que le code propertyChanged a été supprimé pour simplifier les choses):
namespace EnumTest
{
public class Test : INotifyPropertyChanged
{
private TestEnum _MyVar;
public TestEnum MyVar {
get { return _MyVar; }
set
{
_MyVar = value;
OnPropertyChanged("MyVar");
}
}
public Test()
{
_MyVar = TestEnum.three;
}
}
}
fichier programme qui utilise la classe:
namespace EnumTest
{
public partial class Window1 : Window
{
Test _oTest = new Test();
public Window1()
{
InitializeComponent();
cmbBox.DataContext = _oTest;
}
}
}
méthode d'extension pour l'affichage de l'énumération
namespace EnumTest
{
[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);
}
}
}
Et le code XAML qui est utilisé pour afficher les données: d'être défini
<Window x:Class="EnumTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:w="clr-namespace:EnumTest"
Title="Window1" Height="300" Width="300">
<Grid>
<ComboBox Name="cmbBox"
Height="20"
Width="80"
ItemsSource="{Binding Source={w:EnumValues EnumType=w:TestEnum}}"
SelectedItem="{Binding Path=MyVar}"
/>
</Grid>
</Window>
Ce qui précède est tout bon et dandy, mais je veux définir l'Enum au sein la classe d'essai et fossé ENUM au portée mondiale. Comme si:
namespace EnumTest
{
public class Test : INotifyPropertyChanged
{
// Declare Enum **INSIDE** the class
public enum TestEnum {one, two, three, four };
private TestEnum _MyVar;
public TestEnum MyVar {
get { return _MyVar; }
set
{
_MyVar = value;
OnPropertyChanged("MyVar");
}
}
public Test()
{
_MyVar = TestEnum.three;
}
}
}
La question SO j'ai parlé allusion à la syntaxe XAML correspondant comme étant:
<ComboBox Name="cmbBox"
...
ItemsSource="{Binding Source={w:EnumValues EnumType=w:Test+TestEnum}}"
...
/>
Mais ce (genre de) ne fonctionne pas pour moi. Quand je fais une nouvelle génération, je reçois un message « Build a réussi » dans la barre d'état VS 2008, mais je reçois aussi une erreur étant signalée dans le XAML
Type 'Test+TestEnum' was not found.
Mais le code est exécuté comme prévu!
Cependant, cela signifie que le concepteur xaml ne chargera pas. Donc, je suis en quelque sorte foutu à faire plus de travail wpf jusqu'à ce que je peux effacer l'erreur xaml.
Je me demande maintenant si c'est un problème VS 2008 SP1, et pas un problème de ma part.
Modifier
- fait ma déclaration de problème plus explicite.
- Essayé 1ère solution de Joel, mais j'ai fini avec le code en cours d'exécution et 2 erreurs XAML
- 2ème solution de Essayé Joel et qui a travaillé tout droit sorti de la boîte - je vais donc avec celui-là!
Remarques La question de sorte que je suis le code MarkupExtension d'utilise ce style de syntaxe pour la XAML:
<ComboBox ItemsSource="{w:EnumValues w:TestEnum}"/>
Quand j'utilise que je reçois une erreur de compilation disant que aucun constructeur EnumValues prend 1 paramètre. J'ai fait un peu de googling et cela semble être une erreur dans VS. J'utilise VS 2008 SP1. J'ai vu quelques commentaires qui faisaient allusion à la bêta de VS 2010. Quoi qu'il en soit, c'est pourquoi j'utilise la syntaxe xaml de
<ComboBox ItemsSource="{w:EnumValues EnumType=w:TestEnum}"/>
Comme cette syntaxe fonctionne!
En ce qui concerne l'erreur sur le constructeur, il se produit uniquement dans le concepteur.Cela devrait bien fonctionner autrement. Pour éviter cette erreur, définissez l'extension de balisage dans un assembly séparé. –
@Thomas: J'avais oublié comment le concepteur peut être capricieux sur les types construits quand/où et comment ils les instancient. –
@Joel - Et les programmeurs débutants wpf savent ce genre de chose comment? Sachant mettre une classe dans un ensemble séparé afin de satisfaire une partie de l'outil de construction est plutôt obscur à mon humble avis. Mais je continuerai à m'embarrasser jusqu'à ce que j'aie une compréhension raisonnable. Merci encore. –