Como exemplo, pegue o seguinte código:
public enum ExampleEnum { FooBar, BarFoo }
public class ExampleClass : INotifyPropertyChanged
{
private ExampleEnum example;
public ExampleEnum ExampleProperty
{ get { return example; } { /* set and notify */; } }
}
Eu quero um para vincular a propriedade ExampleProperty a um ComboBox, para que ele mostre as opções "FooBar" e "BarFoo" e funcione no modo TwoWay. Idealmente, quero que minha definição ComboBox seja algo como isto:
<ComboBox ItemsSource="What goes here?" SelectedItem="{Binding Path=ExampleProperty}" />
Atualmente, tenho manipuladores para os eventos ComboBox.SelectionChanged e ExampleClass.PropertyChanged instalados na minha janela onde faço a ligação manualmente.
Existe alguma maneira canônica ou melhor? Você usaria normalmente os conversores e como preencheria a caixa de combinação com os valores certos? Eu nem quero começar o i18n agora.
Editar
Então, uma pergunta foi respondida: Como preencho a ComboBox com os valores corretos.
Recupere valores de Enum como uma lista de seqüências de caracteres por meio de um ObjectDataProvider do método estático Enum.GetValues:
<Window.Resources>
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="ExampleEnumValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="ExampleEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
Isso eu posso usar como uma ItemsSource para minha ComboBox:
<ComboBox ItemsSource="{Binding Source={StaticResource ExampleEnumValues}}"/>
Respostas:
Você pode criar uma extensão de marcação personalizada.
Exemplo de uso:
Na parte superior do seu XAML:
e depois...
E a implementação ...
fonte
ItemsSource
parâmetro. Para manter a visualização e o modelo dissociados, eu precisaria criar uma cópia da enumeração no ViewModel e codificar o ViewModel para traduzir entre os dois ... O que tornaria a solução não tão simples. Ou existe uma maneira de fornecer o próprio tipo do ViewModel?No modelo de exibição, você pode ter:
No XAML, o
ItemSource
vinculaMyEnumTypeValues
e oSelectedItem
vinculaSelectedMyEnumType
.fonte
Prefiro não usar o nome de enum na interface do usuário. Eu prefiro usar um valor diferente para user (
DisplayMemberPath
) e diferente para value (enum neste caso) (SelectedValuePath
). Esses dois valores podem ser compactadosKeyValuePair
e armazenados no dicionário.XAML
C #
EDIT: Compatível com o padrão MVVM.
fonte
Enum.GetValues
, mas isso não resolveria a parte dos nomes a serem exibidos. No final, e especialmente se o I18n for implementado, você precisará alterar manualmente as coisas se a enumeração mudar. Mas as enums não devem mudar com frequência, se é que existem? 1public Dictionary<ExampleEnum, string> ExampleEnumsWithCaptions { get; } = new Dictionary<ExampleEnum, string>() { {ExampleEnum.FooBar, "Foo Bar"}, {ExampleEnum.BarFoo, "Reversed Foo Bar"}, //{ExampleEnum.None, "Hidden in UI"}, };
Não sei se é possível apenas em XAML, mas tente o seguinte:
Dê um nome à sua ComboBox para que você possa acessá-la no código abaixo: "typesComboBox1"
Agora tente o seguinte
fonte
Com base na resposta aceita, mas agora excluída, fornecida por ageektrapped , criei uma versão reduzida, sem alguns dos recursos mais avançados. Todo o código está incluído aqui para permitir que você copie e cole e não seja bloqueado pelo link-rot.
Eu uso o
System.ComponentModel.DescriptionAttribute
que realmente se destina a descrições de tempo de design. Se você não gosta de usar esse atributo, pode criar o seu próprio, mas acho que usar esse atributo realmente faz o trabalho. Se você não usar o atributo, o nome usará como padrão o nome do valor da enumeração no código.Aqui está a classe usada como fonte dos itens:
Você pode usá-lo no XAML assim:
fonte
Use ObjectDataProvider:
e, em seguida, vincule ao recurso estático:
Encontre esta solução neste blog
fonte
Converter
de enum-to-string.Minha maneira favorita de fazer isso é com um
ValueConverter
para que o ItemsSource e o SelectedValue sejam vinculados à mesma propriedade. Isso não requer propriedades adicionais para manter seu ViewModel agradável e limpo.E a definição do conversor:
Este conversor funcionará com qualquer enumeração.
ValueDescription
é apenas uma classe simples com umaValue
propriedade e umaDescription
propriedade Você poderia facilmente usar umTuple
comItem1
eItem2
, ou umKeyValuePair
comKey
e emValue
vez de Valor e Descrição ou qualquer outra classe de sua escolha, desde que ela possua um valor de enum e uma descrição de string desse valor de enum.fonte
ValueDescription
classe, aDescription
propriedade pode ser omitida se não for necessário. Uma classe simples com apenasValue
propriedade também funciona!.Select(e => e.ToString())
, em vez de usar aValueDescription
classe.ValueDescription
também umKeyValuePair
poderia ser usado, como mostrado aqui #Aqui está uma solução genérica usando um método auxiliar. Isso também pode manipular uma enumeração de qualquer tipo subjacente (byte, sbyte, uint, long etc.)
Método auxiliar:
Ver modelo:
Caixa combo:
fonte
você pode considerar algo assim:
defina um estilo para o bloco de texto ou qualquer outro controle que você deseja usar para exibir sua enumeração:
defina seu estilo para ComboBoxItem
adicione uma caixa de combinação e carregue-a com seus valores de enumeração:
se sua enumeração for grande, é claro que você pode fazer o mesmo no código, poupando muita digitação. Eu gosto dessa abordagem, uma vez que facilita a localização - você define todos os modelos uma vez e depois atualiza apenas seus arquivos de recursos de string.
fonte
Se você estiver usando um MVVM, com base na resposta @rudigrobler, faça o seguinte:
Adicione a seguinte propriedade à classe ViewModel
Em seguida, no XAML, faça o seguinte:
fonte
Esta é uma
DevExpress
resposta específica com base na resposta mais votada porGregor S.
(atualmente ela possui 128 votos).Isso significa que podemos manter o estilo consistente em todo o aplicativo:
Infelizmente, a resposta original não funciona com um
ComboBoxEdit
DevExpress sem algumas modificações.Primeiro, o XAML para
ComboBoxEdit
:Desnecessário dizer que você precisará apontar
xamlExtensions
para o espaço para nome que contém a classe de extensão XAML (que é definida abaixo):E temos que apontar
myEnum
para o espaço para nome que contém a enumeração:Então, o enum:
O problema com o XAML é que não podemos usá-lo
SelectedItemValue
, pois isso gera um erro, pois o setter é inacessível (um pouco de supervisão de sua parteDevExpress
). Portanto, temos que modificar nossoViewModel
para obter o valor diretamente do objeto:Para completar, eis a extensão XAML da resposta original (levemente renomeada):
Isenção de responsabilidade: não tenho afiliação com o DevExpress. Telerik também é uma ótima biblioteca.
fonte
Tente usar
fonte
Eu criei um projeto CodePlex de código aberto que faz isso. Você pode baixar o pacote NuGet aqui .
fonte