2009-11-21 4 views
1

Salutations,WPF: Définition d'une liaison pour toutes les instances TreeViewItem

J'utilise WPF avec un modèle Model-View-ViewModel, et j'ai un modèle de vue avec une propriété IsSelected que je veux lier à un TreeViewItemIsSelected propriété pour tous TreeViewItem s dans la portée. Je tente de le faire avec un Style et un Setter. Cela fonctionne apparemment pour le niveau racine TreeViewItem s, mais pas pour leurs enfants. Pourquoi est-ce? Comment puis-je l'appliquer à tous les contrôles TreeViewItem?

Voici la vue XAML:

<UserControl x:Class="MyApp.AllAreasView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:MyApp="clr-namespace:MyApp" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="700"> 
<UserControl.Resources> 
    <Style TargetType="{x:Type TreeViewItem}"> 
     <Setter Property="IsSelected" 
       Value="{Binding IsSelected, Mode=TwoWay}"/> 
    </Style> 

    <MyApp:CountVisibilityConverter x:Key="CountVisibilityConverter" /> 

    <HierarchicalDataTemplate x:Key="AreaTemplate" 
           DataType="AreaViewModel" 
           ItemsSource="{Binding Path=SubareasCollectionView}"> 
     <WrapPanel> 
      <TextBlock Text="{Binding Path=Name}" Margin="0 0 8 0" /> 
      <TextBlock DataContext="{Binding Path=Subareas}" 
         Text="{Binding Path=Count, StringFormat= (\{0\})}" 
         Visibility="{Binding Path=Count, Converter={StaticResource CountVisibilityConverter}}" /> 
     </WrapPanel> 
    </HierarchicalDataTemplate> 
</UserControl.Resources> 

<TreeView ItemsSource="{Binding TopLevelAreas}" 
      ItemTemplate="{StaticResource AreaTemplate}"> 
</TreeView> 

</UserControl> 

Répondre

3

Je pense que nous aurons besoin de plus d'informations pour répondre à votre question. Plus précisément, à quoi ressemble votre (vos) modèle (s) de vue. Voici un exemple que vous pouvez copier et coller qui fonctionne bien.

Window1.xaml:

<Window x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication1" 
    Title="Window1" Height="300" Width="300"> 
    <Window.Resources> 
     <Style TargetType="{x:Type TreeViewItem}"> 
      <Setter Property="Background" Value="{Binding Background}"/> 
     </Style> 

     <HierarchicalDataTemplate x:Key="ItemTemplate" DataType="local:DataItem" ItemsSource="{Binding Path=Children}"> 
      <TextBlock Text="{Binding Name}" /> 
     </HierarchicalDataTemplate> 
    </Window.Resources> 

    <TreeView ItemsSource="{Binding}" ItemTemplate="{StaticResource ItemTemplate}"/> 
</Window> 

Window1.xaml.cs:

using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Windows; 
using System.Windows.Media; 

namespace WpfApplication1 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 

      var dis = new ObservableCollection<DataItem>(); 
      var di = new DataItem() { Name = "Top", Background = Brushes.Red }; 
      di.Children.Add(new DataItem() { Name = "Second", Background = Brushes.Blue }); 

      dis.Add(di); 
      DataContext = dis; 
     } 
    } 

    public class DataItem 
    { 
     public DataItem() 
     { 
      Children = new ObservableCollection<DataItem>(); 
     } 

     public string Name 
     { 
      get; 
      set; 
     } 

     public ICollection<DataItem> Children 
     { 
      get; 
      set; 
     } 

     public Brush Background 
     { 
      get; 
      set; 
     } 
    } 
} 
+0

Merci pour avoir l'exemple de travail (et déduisant le modèle simple vue). Il s'avère que j'avais généré deux ensembles distincts de modèles de vue et l'événement PropertyChanged n'était pas géré correctement sur mes modèles de vue depuis que j'avais accroché un, et WPF l'autre. En suivant la piste de l'événement et en examinant les résultats de GetInvocationList() du délégué PropertyChanged, amenez-moi à trouver ceci. Puisque vous avez prouvé que cela fonctionne, je vais accepter cela comme réponse. – codekaizen

0

travailler avec des modèles de vue, vous obtiendrez très sympathique avec la propriété ItemContainerStyle. ce que vous faisiez dans votre code définissait le modèle de données pour le niveau racine. ce que vous voulez faire est de styliser chacun des éléments dans l'arborescence, ce que vous pouvez faire comme ça.

<TreeView ItemsSource="{Binding TopLevelAreas}" 
      ItemContainerStyle="{StaticResource AreaTemplate}"> 
</TreeView> 

profiter

0

Vous devez utiliser comme mentionné ci-dessous. Exploitez l'option BasedOn

<TreeView ItemsSource="{Binding TopLevelAreas}"> 
    <TreeView.Resources> 
      <Style TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource StyleKey}"/> 
    </TreeView.Resources> 
</TreeView> 
+0

Merci d'avoir ressuscité cela, mais comme indiqué sur la réponse acceptée, mon problème était un DataContext incorrect: Je n'obtenais pas de notifications de changement de propriété du modèle de vue puisque je ne le réglais pas correctement sur la vue. Ce modèle fonctionne sans avoir besoin de définir 'BasedOn' dans le style, et en fait, puisque' StyleKey' n'existe pas dans le dictionnaire de ressources, cela le casserait. – codekaizen

Questions connexes