Como recuperar o item selecionado em uma exibição em árvore do WPF? Eu quero fazer isso em XAML, porque eu quero vinculá-lo.
Você pode pensar que é, SelectedItem
mas aparentemente o que não existe, é somente leitura e, portanto, inutilizável.
Isto é o que eu quero fazer:
<TreeView ItemsSource="{Binding Path=Model.Clusters}"
ItemTemplate="{StaticResource ClusterTemplate}"
SelectedItem="{Binding Path=Model.SelectedCluster}" />
Eu quero vincular a SelectedItem
uma propriedade no meu Model.
Mas isso me dá o erro:
A propriedade 'SelectedItem' é somente leitura e não pode ser configurada a partir da marcação.
Edit: Ok, esta é a maneira que eu resolvi isso:
<TreeView
ItemsSource="{Binding Path=Model.Clusters}"
ItemTemplate="{StaticResource HoofdCLusterTemplate}"
SelectedItemChanged="TreeView_OnSelectedItemChanged" />
e no codebehindfile do meu xaml:
private void TreeView_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
Model.SelectedCluster = (Cluster)e.NewValue;
}
Respostas:
Sei que isso já teve uma resposta aceita, mas reuni isso para resolver o problema. Ele usa uma idéia semelhante à solução da Delta, mas sem a necessidade de subclassificar o TreeView:
Você pode usar isso no seu XAML como:
Espero que ajude alguém!
fonte
{Binding SelectedItem, Mode=TwoWay}
por{Binding MyViewModelField, Mode=TwoWay}
xmlns:e="http://schemas.microsoft.com/expression/2010/interactivity"
Esta propriedade existe: TreeView.SelectedItem
Mas é somente leitura, portanto, você não pode atribuí-lo por meio de uma ligação, apenas recuperá-lo
fonte
TreeView.SelectedItem
afetar uma propriedade no modelo quando o usuário seleciona um item (akaOneWayToSource
)?Responda com propriedades anexadas e sem dependências externas, caso seja necessário!
Você pode criar uma propriedade anexada que seja vinculável e tenha um getter e um setter:
Adicione a declaração do espaço para nome que contém essa classe ao seu XAML e ligue-a da seguinte forma (local é como nomeei a declaração do espaço para nome):
Agora você pode vincular o item selecionado e também configurá-lo no seu modelo de exibição para alterá-lo programaticamente, caso esse requisito ocorra. Obviamente, isso pressupõe que você implementa INotifyPropertyChanged nessa propriedade específica.
fonte
Bem, eu encontrei uma solução. Move a bagunça, para que o MVVM funcione.
Primeiro adicione esta classe:
e adicione isso ao seu xaml:
fonte
Responde um pouco mais do que o OP está esperando ... Mas espero que possa ajudar alguém pelo menos.
Se você deseja executar um
ICommand
sempre queSelectedItem
alterado, é possível vincular um comando em um evento e o uso de uma propriedadeSelectedItem
noViewModel
não será mais necessário.Para fazer isso:
1- Adicione referência a
System.Windows.Interactivity
2- Vincule o comando ao evento
SelectedItemChanged
fonte
System.Windows.Interactivity
pode ser instalado a partir NuGet: nuget.org/packages/System.Windows.Interactivity.WPFSystem.Windows.Interactivity
. Foi trabalhado para mim (tentei com o projeto .NET Core). Para definir as coisas, basta adicionar o pacote de nuget Microsoft.Xaml.Behaviors.Wpf , altere o espaço para nomexmlns:i="http://schemas.microsoft.com/xaml/behaviors"
. Para obter mais informações - consulte o blogIsso pode ser feito de uma maneira 'melhor', usando apenas a ligação e o EventToCommand da biblioteca GalaSoft MVVM Light. Na sua VM, adicione um comando que será chamado quando o item selecionado for alterado e inicialize o comando para executar qualquer ação necessária. Neste exemplo, usei um RelayCommand e defina apenas a propriedade SelectedCluster.
Em seguida, adicione o comportamento EventToCommand no seu xaml. Isso é realmente fácil usando a mistura.
fonte
Tudo complicado ... Vá com o Caliburn Micro (http://caliburnmicro.codeplex.com/)
Visão:
ViewModel:
fonte
Encontrei esta página procurando a mesma resposta que o autor original e, provando que sempre há mais de uma maneira de fazê-lo, a solução para mim foi ainda mais fácil do que as respostas fornecidas aqui até agora, então achei que seria melhor adicionar para a pilha.
A motivação para a ligação é mantê-la agradável e MVVM. O uso provável do ViewModel é ter uma propriedade com um nome como "CurrentThingy" e, em outro lugar, o DataContext em alguma outra coisa está vinculado a "CurrentThingy".
Em vez de passar por etapas adicionais necessárias (por exemplo: comportamento personalizado, controle de terceiros) para oferecer suporte a uma boa ligação do TreeView ao meu modelo e, depois, de outra coisa ao meu modelo, minha solução foi usar o simples elemento de ligação à outra coisa para TreeView.SelectedItem, em vez de vincular a outra coisa ao meu ViewModel, ignorando o trabalho extra necessário.
XAML:
Obviamente, isso é ótimo para ler o item atualmente selecionado, mas não defini-lo, o que é tudo o que eu precisava.
fonte
Você também pode usar a propriedade TreeViewItem.IsSelected
fonte
Também há uma maneira de criar a propriedade SelectedItem vinculável por XAML sem usar Interaction.Behaviors.
Você pode usar isso no seu XAML como:
fonte
Eu tentei todas as soluções dessas perguntas. Ninguém resolveu meu problema completamente. Então, acho melhor usar essa classe herdada com a propriedade redefinida SelectedItem. Funcionará perfeitamente se você escolher o elemento de árvore da GUI e se definir esse valor da propriedade no seu código
fonte
Meu requisito era a solução baseada em PRISM-MVVM, em que um TreeView era necessário e o objeto vinculado é do tipo Collection <> e, portanto, precisa de HierarchicalDataTemplate. O padrão BindableSelectedItemBehavior não poderá identificar o filho TreeViewItem. Para fazê-lo funcionar neste cenário.
Isso permite percorrer todos os elementos, independentemente do nível.
fonte
Sugiro uma adição ao comportamento fornecido por Steve Greatrex. Seu comportamento não reflete as alterações da fonte porque pode não ser uma coleção de TreeViewItems. Portanto, é uma questão de encontrar o TreeViewItem na árvore em que datacontext é o selectedValue da origem. O TreeView tem uma propriedade protegida chamada "ItemsHost", que contém a coleção TreeViewItem. Podemos refleti-lo e percorrer a árvore procurando o item selecionado.
Dessa forma, o comportamento funciona para ligações bidirecionais. Como alternativa, é possível mover a aquisição de ItemsHost para o método OnAttached do Behavior, economizando a sobrecarga de usar reflexão sempre que a ligação for atualizada.
fonte
WPF MVVM TreeView SelectedItem
... é uma resposta melhor, mas não menciona uma maneira de obter / definir o SelectedItem no ViewModel.
fonte
Depois de estudar na Internet por um dia, encontrei minha própria solução para selecionar um item depois de criar uma visualização em árvore normal em um ambiente WPF / C # normal
fonte
Isso também pode ser feito usando a propriedade IsSelected do item TreeView. Aqui está como eu consegui,
Em seguida, no ViewModel que contém os dados aos quais o TreeView está vinculado, basta se inscrever no evento na classe TreeViewItem.
E, finalmente, implemente esse manipulador no mesmo ViewModel,
E a ligação, é claro,
fonte
Eu sei que esta discussão tem 10 anos, mas o problema ainda existe ....
A pergunta original era 'recuperar' o item selecionado. Eu também precisava "obter" o item selecionado no meu modelo de exibição (não configurá-lo). De todas as respostas neste tópico, a de 'Wes' é a única que aborda o problema de maneira diferente: se você pode usar o 'Item selecionado' como um destino para a ligação de dados, use-o como uma fonte para a ligação de dados. Wes fez isso em outra propriedade view, farei isso em uma propriedade viewmodel:
Precisamos de duas coisas:
Viewmodel:
Ver construtor:
fonte
(Vamos todos concordar que o TreeView está obviamente bloqueado em relação a esse problema. A ligação ao SelectedItem teria sido óbvia. Suspiro )
Eu precisava da solução para interagir corretamente com a propriedade IsSelected de TreeViewItem, então veja como eu fiz isso:
Com este XAML:
fonte
Trago a você minha solução, que oferece os seguintes recursos:
Suporta 2 maneiras de ligação
Atualiza automaticamente as propriedades TreeViewItem.IsSelected (de acordo com o SelectedItem)
Nenhuma subclasse de TreeView
Os itens vinculados ao ViewModel podem ser de qualquer tipo (até nulos)
1 / Cole o seguinte código no seu CS:
2 / Exemplo de uso no seu arquivo XAML
fonte
Proponho esta solução (que considero mais fácil e sem vazamentos de memória), que funciona perfeitamente para atualizar o item selecionado do ViewModel a partir do item selecionado do View.
Observe que a alteração do item selecionado no ViewModel não atualizará o item selecionado da View.
Uso de XAML
fonte