Em um aplicativo WPF usando MVVM, eu tenho um controle de usuário com um item de exibição de lista. Em tempo de execução, ele usará databinding para preencher o listview com uma coleção de objetos.
Qual é a maneira correta de anexar um evento de clique duplo aos itens na visualização em lista para que, quando um item na visualização em lista for clicado duas vezes, um evento correspondente no modelo de visualização seja disparado e tenha uma referência ao item clicado?
Como isso pode ser feito de uma forma MVVM limpa, ou seja, sem código atrás no View?
Consigo fazer isso funcionar com o .NET 4.5. Parece simples e nenhum terceiro ou código é necessário.
fonte
InputBindings
estão disponíveis no .NET 3.0 e não estão disponíveis no Silverlight.Eu gosto de usar comportamentos e comandos de comando anexados . Marlon Grech tem uma implementação muito boa do Attached Command Behaviors. Usando isso, poderíamos atribuir um estilo à propriedade ItemContainerStyle do ListView que definirá o comando para cada ListViewItem.
Aqui definimos o comando a ser disparado no evento MouseDoubleClick, e o CommandParameter, será o objeto de dados no qual clicaremos. Aqui estou subindo na árvore visual para obter o comando que estou usando, mas você poderia facilmente criar comandos para todo o aplicativo.
Para os comandos, você pode implementar um ICommand diretamente ou usar alguns dos ajudantes como aqueles que vêm no MVVM Toolkit .
fonte
acb:
= AttachedCommandBehavior. O código pode ser encontrado no primeiro link da respostaEu descobri uma maneira muito fácil e limpa de fazer isso com os gatilhos de eventos do Blend SDK. MVVM limpo, reutilizável e sem code-behind.
Você provavelmente já tem algo assim:
Agora inclua um ControlTemplate para ListViewItem como este se você ainda não usa um:
O GridViewRowPresenter será a raiz visual de todos os elementos "internos" que constituem um elemento de linha da lista. Agora poderíamos inserir um gatilho lá para procurar eventos roteados MouseDoubleClick e chamar um comando por meio de InvokeCommandAction como este:
Se você tiver elementos visuais "acima" do GridRowPresenter (provavelmente começando com uma grade), você também pode colocar o Trigger lá.
Infelizmente, os eventos MouseDoubleClick não são gerados a partir de todos os elementos visuais (eles são de Controls, mas não de FrameworkElements, por exemplo). Uma solução alternativa é derivar uma classe de EventTrigger e procurar MouseButtonEventArgs com ClickCount de 2. Isso filtra efetivamente todos os não-MouseButtonEvents e todos os MoseButtonEvents com ClickCount! = 2.
Agora podemos escrever isso ('h' é o namespace da classe auxiliar acima):
fonte
Sei que essa discussão já existe há um ano, mas com o .NET 4, há alguma ideia sobre essa solução? Eu concordo totalmente que o objetivo do MVVM NÃO é eliminar um arquivo code-behind. Também sinto fortemente que só porque algo é complicado, não significa que seja melhor. Aqui está o que coloquei no código por trás:
fonte
Você pode usar o recurso Action do Caliburn para mapear eventos para métodos em seu ViewModel. Supondo que você tenha um
ItemActivated
método em seuViewModel
, o XAML correspondente seria semelhante a:Para obter mais detalhes, você pode examinar a documentação e as amostras do Caliburn.
fonte
Estou achando mais simples vincular o comando quando a visualização é criada:
No meu caso se
BindAndShow
parece com isto (updatecontrols + avalondock):Embora a abordagem deva funcionar com qualquer método que você tenha para abrir novas visualizações.
fonte
Eu vi a solução do rushui com o InuptBindings, mas ainda não consegui acertar a área do ListViewItem onde não havia texto - mesmo depois de definir o fundo como transparente, então resolvi usando diferentes modelos.
Este modelo é para quando o ListViewItem foi selecionado e está ativo:
Este modelo é para quando o ListViewItem foi selecionado e está inativo:
Este é o estilo padrão usado para ListViewItem:
O que eu não gosto é a repetição do TextBlock e sua vinculação de texto, não sei se posso declarar isso em apenas um local.
Espero que isso ajude alguém!
fonte
listviewitem
, provavelmente não se importará se já está selecionado ou não. Também é importante observar que o efeito de realce também pode precisar ser ajustado para combinar com olistview
estilo. Votado.Consigo fazer essa funcionalidade com a estrutura .Net 4.7 usando a biblioteca de interatividade, antes de mais nada, certifique-se de declarar o namespace no arquivo XAML
Em seguida, defina o Event Trigger com seu respectivo InvokeCommandAction dentro do ListView como abaixo.
Visão:
Adaptar o código acima deve ser o suficiente para fazer o evento de clique duplo funcionar em seu ViewModel, no entanto, adicionei a você a classe Model e a classe View Model do meu exemplo para que você tenha uma ideia completa.
Modelo:
Ver modelo:
Caso você precise da implementação da classe DelegateCommand .
fonte
Aqui está um comportamento que faz isso em ambos
ListBox
eListView
.Aqui está a classe de extensão usada para localizar o pai.
Uso:
fonte