How to get updated automatically WPF TreeViewItems with values based on .Net class properties?

谁说我不能喝 提交于 2019-12-11 07:30:01

问题


Good morning. I have a class with data derived from InotifyPropertyChange. The data come from a background thread, which searches for files with certain extension in certain locations. Public property of the class reacts to an event OnPropertyChange by updating data in a separate thread. Besides, there are described in XAML TreeView, based on HierarhicalDataTemplates. Each TextBlock inside templates supplied 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: Why is the data from a class derived from INotifyPropertyChange does not affect the display of tree items. Do I understand: The interface will make INotifyPropertyChange be automatically redrawn TreeViewItems or do I need to manually carry out this operation? Currently TreeViewItems not updated and PropertyChamged always null. A feeling that no subscribers to the event OnPropertyChanged.


回答1:


You don't need to set the NotifyOnTargetUpdated.

Instead, make sure to raise the PropertyChanged event (with the appropriate property-name passed with the PropertyChangedEventArgs passed to the handler) on the parent entity each time the paths collection is updated, or have the navigation property be an implementation of INotifyCollectionChanged.




回答2:


I think I found the reason. My background thread that constantly scans the folder creates a new instance of the data class derived from INotifyPropertyChanged, which serves as a source for TreeViewItems (ItemsSource). This principle is chosen because it is impossible to predict what should be done with a collection of files found: add a new item, remove an existing or edit an existing. If I ever intended to substitute ItemsSource trick with PropertyChange does not work. So for me the only solution was to call from the separate (background, scanning folders) thread Refresh() method for 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();
}

Use of this situation with these classes inherited from INotifyPropertyChanged useless. ItemsControl, you bind to this class expects only add, delete or change items, but not replace ItemsSource a new instance of the data class.



来源:https://stackoverflow.com/questions/4533107/how-to-get-updated-automatically-wpf-treeviewitems-with-values-based-on-net-cla

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!