如何使用基于.NET类属性的值自动更新的WPF TreeViewItems?
-
13-10-2019 - |
题
早上好。我有一个来自InotifyPropertyChange的数据。数据来自背景线程,该线程在某些位置搜索具有某些扩展名的文件。类的公共属性通过在单独线程中更新数据来对事件onPropertyChange做出反应。此外,基于hierarhicaldatatemplates中的XAML Treeview中描述了。模板中的每个文本块提供了itemssource =“ {binding fundfilepaths,mode = oneway,notifyOntifyOntifyOntargetUpdated = 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未更新和属性捕获始终为空。这种感觉没有订阅该事件的人。
解决方案
您不需要设置 NotifyOnTargetUpdated
.
相反,请确保提高 PropertyChanged
事件(并通过适当的属性名称通过 PropertyChangedEventArgs
每次更新路径集合时,传递给父母实体的处理程序) INotifyCollectionChanged
.
其他提示
我想我找到了原因。我的背景线程不断扫描该文件夹会创建从InotifyPropertychanged派生的数据类的新实例,该实例是TreeViewItems(itempsSource)的来源。之所以选择此原则,是因为无法预测发现的文件集合应该完成的操作:添加新项目,删除现有或编辑现有的现有。如果我曾经打算用propertyChange替换物品的技巧,则行不通。因此,对我而言,唯一的解决方案是从单独的(背景,扫描文件夹)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,您可以绑定到此类期望仅添加,删除或更改项目,但不替换项目类的新实例。