2

早上好。我有一个从 InotifyPropertyChange 派生的数据的类。数据来自后台线程,该线程在特定位置搜索具有特定扩展名的文件。类的公共属性通过在单独的线程中更新数据来响应 OnPropertyChange 事件。此外,还有基于 HierarhicalDataTemplates 的 XAML TreeView 中的描述。模板中的每个 TextBlock 都提供了 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>

问:为什么从 INotifyPropertyChange 派生的类中的数据不影响树项的显示。我是否理解:该界面会使 INotifyPropertyChange 自动重绘 TreeViewItems 还是我需要手动执行此操作?目前 TreeViewItems 未更新,PropertyChamged 始终为空。感觉 OnPropertyChanged 事件没有订阅者。

4

2 回答 2

2

您无需设置NotifyOnTargetUpdated.

相反,请确保每次更新路径集合时在父实体上引发PropertyChanged事件(使用传递给处理程序的适当属性名称),或者让导航属性是.PropertyChangedEventArgsINotifyCollectionChanged

于 2010-12-26T07:47:32.670 回答
0

我想我找到了原因。我不断扫描文件夹的后台线程创建了一个派生自 INotifyPropertyChanged 的​​数据类的新实例,该实例用作 TreeViewItems (ItemsSource) 的源。选择此原则是因为无法预测应该对找到的文件集合执行什么操作:添加新项目、删除现有项目或编辑现有项目。如果我曾经打算用 PropertyChange 替换 ItemsSource 技巧是行不通的。所以对我来说,唯一的解决方案是从单独的(后台、扫描文件夹)线程 Refresh() 方法调用 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();
}

这种情况下使用这些类继承自 INotifyPropertyChanged 没用。ItemsControl,你绑定到这个类期望只添加、删除或改变项目,而不是替换ItemsSource数据类的一个新实例。

于 2010-12-26T12:49:32.633 回答