Comment obtenir automatiquement mis à jour WPF TreeViewItems avec des valeurs basées sur les propriétés de la classe .Net?

StackOverflow https://stackoverflow.com/questions/4533107

Question

Bonjour. J'ai une classe avec des données provenant de InotifyPropertyChange. Les données proviennent d'un fil d'arrière-plan, qui recherche les fichiers avec certaine extension dans certains endroits. Propriété publique de réagit de manière classe à un onPropertyChange d'événement en mettant à jour les données dans un thread séparé. En outre, il est décrit en XAML TreeView, sur la base HierarhicalDataTemplates. Chaque TextBlock à l'intérieur des modèles fournis ItemsSource = "{Binding FoundFilePaths, mode = OneWay, NotifyOnTargetUpdated = true}".

 <TreeView  x:Name="FoundFiles_TreeView"  Opacity="15" Background="White"   BorderThickness="5" FontFamily="Arial" Margin="0,0,0,0" RenderTransformOrigin="0.5,0.5" VerticalAlignment="Top" Height="360" FontWeight="Bold" Foreground="#FF539DBE" TargetUpdated="FoundFiles_TreeView_TargetUpdated">
            <TreeView.ItemContainerStyle >
                <Style TargetType="{x:Type TreeViewItem}">
                    <Setter Property="TreeViewItem.Tag" Value="InfoNode" />
                    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
                    <Setter Property="Foreground" Value="Brown"/>
                    <Style.Triggers>
                        <Trigger Property="IsMouseCaptured" Value="True">
                            <Setter Property="IsSelected" Value="True"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </TreeView.ItemContainerStyle>
            <TreeView.Resources>
                <HierarchicalDataTemplate  DataType = "{x:Type lightvedo:FilesInfoStore}"  ItemsSource="{Binding FoundFilePaths, Mode=OneWay, NotifyOnTargetUpdated=True}">
                    <!--Здесь указываются узлы дерева-->
                    <StackPanel x:Name ="TreeNodeStackPanel" Orientation="Horizontal">
                        <TextBlock Margin="5,5,5,5" TargetUpdated="TextBlockExtensions_TargetUpdated">
         <TextBlock.Text>
          <MultiBinding StringFormat="Files with Extension  {0}">
           <Binding Path="FileExtension"/>
          </MultiBinding>
         </TextBlock.Text>
                        </TextBlock>
                        <Button x:Name="OpenFolderForThisFiles" Click="OnOpenFolderForThisFiles_Click" Margin="5, 3, 5, 3" Width="22" Background="Transparent" BorderBrush="Transparent" BorderThickness="0.5">
                            <Image Source="images\Folder.png" Height="16" Width="20" >
                            </Image>
                        </Button>
                    </StackPanel>
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type lightvedo:FilePathsStore}">
                    <TextBlock Text="{Binding FilePaths, Mode=OneWay, NotifyOnTargetUpdated=True}" TargetUpdated="OnTreeViewNodeChildren_Update" />
                </HierarchicalDataTemplate>
            </TreeView.Resources>
            <TreeView.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform AngleX="-0.083"/>
                    <RotateTransform/>
                    <TranslateTransform X="-0.249"/>
                </TransformGroup>
            </TreeView.RenderTransform>
            <TreeView.BorderBrush>
                <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
                    <GradientStop Color="#FF74591F" Offset="0" />
                    <GradientStop Color="#FF9F7721" Offset="1" />
                    <GradientStop Color="#FFD9B972" Offset="0.49" />
                </LinearGradientBrush>
            </TreeView.BorderBrush>
        </TreeView>

Q: Pourquoi les données d'une classe dérivée de INotifyPropertyChange ne modifie pas l'affichage des éléments d'arbres. Est-ce que je comprends: L'interface fera INotifyPropertyChange automatiquement TreeViewItems réaffiché ou dois-je effectuer manuellement cette opération? Actuellement TreeViewItems pas mis à jour et PropertyChamged toujours nulle. Un sentiment qu'aucun abonné à l'événement OnPropertyChanged.

Était-ce utile?

La solution

Vous n'avez pas besoin de régler la NotifyOnTargetUpdated.

Au lieu de cela, assurez-vous de relever le PropertyChanged événement (avec le approprié nom_propriété passé avec le PropertyChangedEventArgs transmis au gestionnaire) sur l'entité mère à chaque fois que la collection de chemins est mis à jour, ou ont la propriété de navigation est une implémentation de INotifyCollectionChanged .

Autres conseils

Je pense avoir trouvé la raison. Mon fil d'arrière-plan qui scanne en permanence le dossier crée une nouvelle instance de la classe de données provenant de INotifyPropertyChanged, qui sert de source pour TreeViewItems (ItemsSource). Ce principe est choisi parce qu'il est impossible de prédire ce qui devrait être fait avec une collection de fichiers trouvés: ajouter un nouvel élément, supprimer un existant ou modifier un existant. Si jamais je comptais substituer tour ItemsSource avec PropertyChange ne fonctionne pas. Donc, pour moi, la seule solution était d'appeler à partir du séparé (arrière-plan, la numérisation des dossiers) fil méthode Refresh () pour TreeViewItems.

public delegate void RefreshTreeViewItemsDelegate(); 

Dispatcher.FromThread(_guiThread).BeginInvoke(DispatcherPriority.Render, new RefreshTreeViewItemsDelegate (RefreshTreeItems)) 

// Some code ommited

private void RefreshTreeItems()
{
   _popupWindow.FoundFiles_TreeView.ItemsSource = _treeViewNodesItems;
   _popupWindow.FoundFiles_TreeView.Items.Refresh();
}

L'utilisation de cette situation avec ces classes héritées de INotifyPropertyChanged inutiles. ItemsControl, vous lient à cette classe attend seulement ajouter, supprimer ou modifier les articles, mais pas remplacer ItemsSource une nouvelle instance de la classe de données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top