Estou tentando encontrar um exemplo simples onde as enumerações são mostradas como estão. Todos os exemplos que eu vi tentam adicionar seqüências de exibição com boa aparência, mas não quero essa complexidade.
Basicamente, eu tenho uma classe que contém todas as propriedades que eu vinculo, definindo primeiro o DataContext para essa classe e especificando a ligação como esta no arquivo xaml:
<ComboBox ItemsSource="{Binding Path=EffectStyle}"/>
Mas isso não mostra os valores de enumeração nos ComboBox
itens as.
Respostas:
Você pode fazer isso a partir do código, colocando o seguinte código no
Loaded
manipulador de eventos do Windows , por exemplo:Se você precisar vinculá-lo ao XAML, precisará
ObjectDataProvider
criar o objeto disponível como fonte de vinculação:Chame a atenção para o próximo código:
Guia como mapear o namespace e o assembly que você pode ler no MSDN .
fonte
xmlns:DllAlias="clr-namespace:NamespaceInsideDll; assembly=DllAssemblyName"
XAML para usá-lo. Aqui está o guia: msdn.microsoft.com/en-us/library/ms747086.aspxEu gosto de todos os objetos que estou vinculando a serem definidos no meu
ViewModel
, então tento evitar o uso<ObjectDataProvider>
no xaml quando possível.Minha solução não usa dados definidos no modo de exibição e nenhum code-behind. Apenas um DataBinding, um ValueConverter reutilizável, um método para obter uma coleção de descrições para qualquer tipo de Enum e uma única propriedade no ViewModel à qual se vincular.
Quando eu quero vincular um
Enum
aoComboBox
texto que eu quero exibir nunca corresponde aos valores doEnum
, então eu uso o[Description()]
atributo para fornecer o texto que eu realmente quero ver noComboBox
. Se eu tivesse um enum de dias da semana, seria algo como isto:Primeiro, criei a classe helper com alguns métodos para lidar com enumerações. Um método obtém uma descrição para um valor específico, o outro método obtém todos os valores e suas descrições para um tipo.
Em seguida, criamos um
ValueConverter
. A herança deMarkupExtension
facilita o uso no XAML, para que não seja necessário declará-lo como um recurso.Minha
ViewModel
única precisa de 1 propriedade que meuView
pode vincular para oSelectedValue
eItemsSource
da caixa de combinação:E, finalmente, para vincular a
ComboBox
exibição (usando oValueConverter
naItemsSource
vinculação) ...Para implementar esta solução, você só precisa copiar minha
EnumHelper
classe eEnumToCollectionConverter
classe. Eles vão trabalhar com qualquer enumeração. Além disso, não a incluí aqui, mas aValueDescription
classe é apenas uma classe simples com 2 propriedades de objetos públicos, uma chamadaValue
e outra chamadaDescription
. Você pode criar isso sozinho ou alterar o código para usar umTuple<object, object>
ouKeyValuePair<object, object>
fonte
ValueDescription
classe que tem propriedades públicas paraValue
eDescription
Tuple<T1, T2>
ou ou emKeyValuePair<TKey, TValue>
vez daValueDescription
classe e não precisará criar o seu próprio.Eu usei outra solução usando o MarkupExtension.
Eu fiz classe que fornece itens de origem:
Isso é quase tudo ... Agora use-o no XAML:
Alterar 'enums: States' para sua enum
fonte
e.ToString()
nome para exibição. Você pode usar seu próprio tradutor, analisador de atributos de descrição, o que for.{Binding Path=WhereEverYouWant}
) e, se desejar que ela suporte a ligação bidirecional, também terá um campo de apoio para ela. Portanto, você não está substituindo duas propriedades e um campo de apoio ao fazer isso, mas apenas uma propriedade de linha única de leitura.Use ObjectDataProvider:
e, em seguida, vincule ao recurso estático:
com base neste artigo
fonte
xmlns:System="clr-namespace:System;assembly=mscorlib"
A resposta de Nick realmente me ajudou, mas eu percebi que poderia ser um pouco modificado, para evitar uma classe extra, ValueDescription. Lembrei-me de que já existe uma classe KeyValuePair na estrutura, portanto, isso pode ser usado.
O código muda apenas um pouco:
e finalmente o XAML:
Espero que isso seja útil para os outros.
fonte
KeyValuePair
mas no final decidi usar aKeyValuePair
para representar algo que não é um par de valores-chave, apenas para evitar escrever uma classe trivialmente simples não fazia muito sentido. AValueDescription
classe tem apenas 5 linhas, e 2 delas são justas{
e}
Você precisará criar uma matriz dos valores na enumeração, que pode ser criada chamando System.Enum.GetValues () , passando
Type
a enumeração da qual você deseja os itens.Se você especificar isso para a
ItemsSource
propriedade, ela deverá ser preenchida com todos os valores da enumeração. Você provavelmente deseja vincularSelectedItem
aEffectStyle
(assumindo que seja uma propriedade da mesma enumeração e contenha o valor atual).fonte
Todas as postagens acima perderam um truque simples. É possível, a partir da ligação de SelectedValue, descobrir como preencher o ItemsSource AUTOMAGICAMENTE, para que sua marcação XAML seja justa.
Por exemplo, no meu ViewModel eu tenho
ValidateRaiseAndSetIfChanged é meu gancho INPC. O seu pode ser diferente.
A implementação do EnumComboBox é a seguinte, mas primeiro precisarei de um pouco de ajuda para obter minhas seqüências e valores de enumeração
e a classe principal (note que estou usando o ReactiveUI para conectar alterações de propriedade via WhenAny)
Você também precisa definir o estilo corretamente no Generic.XAML ou a sua caixa não renderizará nada e você arrancará o cabelo.
e é isso. Obviamente, isso poderia ser estendido para suportar o i18n, mas tornaria o post mais longo.
fonte
Aplicativos universais parecem funcionar um pouco diferente; ele não tem todo o poder do XAML completo. O que funcionou para mim é:
Apenas por diversão, criei uma turma pequena para ajudá-lo e publiquei-a nas páginas de amostras do MSDN . Os bits extras permitem que eu substitua opcionalmente os nomes das enumerações e deixe-me ocultar algumas delas. Meu código se parece muito com o de Nick (acima), que eu gostaria de ter visto anteriormente.
fonte
Existem muitas respostas excelentes para essa pergunta e eu humildemente submeto a minha. Acho que o meu é um pouco mais simples e mais elegante. Requer apenas um conversor de valor.
Dado um enum ...
e um conversor de valor ...
Recursos...
Declaração XAML ...
Ver modelo ...
Caixa de combinação resultante ...
fonte
Você deve estender a resposta de Rogers e Greg com esse tipo de conversor de valor Enum, se estiver vinculando diretamente as propriedades do modelo de objeto enum.
fonte
Se você está vinculando a uma propriedade enum real no seu ViewModel, não a uma representação int de uma enum, as coisas ficam complicadas. Achei que é necessário vincular à representação da string, NÃO o valor int, como é esperado em todos os exemplos acima.
Você pode saber se esse é o caso, vinculando uma caixa de texto simples à propriedade que você deseja vincular ao seu ViewModel. Se mostrar texto, vincule à string. Se ele mostrar um número, vincule ao valor. Observe que usei o Display duas vezes, o que normalmente seria um erro, mas é a única maneira de funcionar.
Greg
fonte
Gostei da resposta de tom.maruska , mas precisava oferecer suporte a qualquer tipo de enumeração que meu modelo pudesse encontrar em tempo de execução. Para isso, tive que usar uma ligação para especificar o tipo da extensão de marcação. Consegui trabalhar nesta resposta de nicolay.anykienko para criar uma extensão de marcação muito flexível que funcionaria em qualquer caso em que eu pudesse pensar. É consumido assim:
A fonte da extensão de marcação amassada mencionada acima:
fonte
Explicação simples e clara: http://brianlagunas.com/a-better-way-to-data-bind-enums-in-wpf/
...
...
fonte
Usando
ReactiveUI
, eu criei a seguinte solução alternativa. Não é uma solução multifuncional elegante, mas acho que pelo menos é legível.No meu caso, vincular uma lista de
enum
a um controle é um caso raro, portanto, não preciso escalar a solução na base de código. No entanto, o código pode ser tornado mais genérico mudandoEffectStyleLookup.Item
para umObject
. Eu testei com o meu código, nenhuma outra modificação é necessária. O que significa que a classe auxiliar pode ser aplicada a qualquerenum
lista. Embora isso reduzisse sua legibilidade -ReactiveList<EnumLookupHelper>
não tem um grande toque.Usando a seguinte classe auxiliar:
No ViewModel, converta a lista de enumerações e exponha-a como uma propriedade:
No
ComboBox
, utilize oSelectedValuePath
propriedade, para vincular aoenum
valor original :Na visualização, isso nos permite vincular o original
enum
aoSelectedEffectStyle
no ViewModel, mas exibir oToString()
valor noComboBox
:fonte
Estou adicionando meu comentário (no VB, infelizmente, mas o conceito pode ser facilmente replicado para C # em um piscar de olhos), porque eu apenas precisei fazer referência a isso e não gostei de nenhuma das respostas, pois eram muito complexas. Não deveria ter que ser tão difícil.
Então, eu vim com uma maneira mais fácil. Vincule os enumeradores a um dicionário. Vincule esse dicionário à caixa de combinação.
Minha caixa de combinação:
Meu code-behind. Felizmente, isso ajuda alguém.
fonte
A solução de Nick pode ser mais simplificada, sem nada demais, você precisaria apenas de um único conversor:
Você então usa isso onde quer que sua caixa de combinação apareça:
fonte
Eu não recomendaria implementar isso como está, mas espero que isso possa inspirar uma boa solução.
Digamos que seu enum é Foo. Então você pode fazer algo assim.
Em seguida, no
Window.Load
método, você pode carregar todas as enumerações para asObservableCollection<FooViewModel>
quais você pode definir como DataContext da caixa de combinação.fonte
Eu apenas mantive isso simples. Criei uma lista de itens com os valores de enumeração no meu ViewModel:
No meu código xaml eu só preciso disso:
fonte