Vinculando um ComboBox a um enum aninhado em uma classe
Eu tenho enlouquecido com a vinculação de uma caixa de combinação a uma propriedade com enumeração de enumeração de uma classe, em que o próprio enum é declarado nessa mesma classe.
Eu estou tentando seguir a resposta fornecida aqui(wpf combobox ligação ao enum o que eu fiz de errado?) Especificamente, estou usando o código MarkupExtension sugerido e o código xaml correspondente.
Meu código de trabalho é:
Definindo o Enum em um arquivo separado.
namespace EnumTest
{
public enum TestEnum {one, two, three, four };
}
Classe que usa o Enum (Observe que o código propertyChanged foi removido para simplificar as coisas):
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;
}
}
}
Arquivo de programa que usa a classe:
namespace EnumTest
{
public partial class Window1 : Window
{
Test _oTest = new Test();
public Window1()
{
InitializeComponent();
cmbBox.DataContext = _oTest;
}
}
}
Método de extensão para exibir o Enum
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);
}
}
}
E o código xaml que é usado para exibir os dados:
<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>
O acima é tudo bom e dandy, mas eu quero definir o Enumdentro a classe Test e impeça o Enum de ser definido no escopo global. Igual a:
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;
}
}
}
A pergunta SO a que me referi alude à sintaxe xaml correspondente como sendo:
<ComboBox Name="cmbBox"
...
ItemsSource="{Binding Source={w:EnumValues EnumType=w:Test+TestEnum}}"
...
/>
Mas isso (mais ou menos) não funciona para mim. Quando faço uma compilação limpa, recebo uma mensagem "Build succeeded" na barra de status do VS 2008, mas também recebo um erro sendo relatado no xaml
Type 'Test+TestEnum' was not found.
Mas o código é executado como esperado!
No entanto, isso significa que o designer xaml não será carregado. Então estou meio que fazendo mais trabalhos wpf até conseguir limpar o erro xaml.
Agora estou querendo saber se isso é um problema do VS 2008 SP1, e não um problema da minha parte.
Editar
Tornei minha declaração de problema mais explícita.Tentei primeira solução de Joel, mas acabei com o código em execuçãoe 2 erros xamlTentei a segunda solução de Joel e que funcionou diretamente fora da caixa - então eu vou com essa!Notas A pergunta SO de que obtive o código MarkupExtension usa esse estilo de sintaxe para o xaml:
<ComboBox ItemsSource="{w:EnumValues w:TestEnum}"/>
Quando eu uso isso, recebo um erro de compilação dizendo que nenhum construtor EnumValues usa 1 parâmetro. Eu fiz algumas googling e isso parece ser um erro no VS. Eu estou usando o VS 2008 SP1. Eu vi alguns comentários que faziam alusão a ele estar no beta do VS 2010. De qualquer forma, é por isso que eu uso a sintaxe xaml de
<ComboBox ItemsSource="{w:EnumValues EnumType=w:TestEnum}"/>
Como esta sintaxe funciona!