.NETクラスのプロパティに基づいて値を持つWPF TreeViewItemsを自動的に更新する方法は?
-
13-10-2019 - |
質問
おはようございます。 inotifypropertychangeから派生したデータを備えたクラスがあります。データは、特定の場所で特定の拡張機能を持つファイルを検索するバックグラウンドスレッドからのものです。クラスの公共財産は、別のスレッドでデータを更新することにより、イベントOnpropertychangeに反応します。また、hierarhicalDatatemplatesに基づいて、Xaml TreeViewに記載されています。テンプレート内の各テキストブロックは項目Source = "{binding finedfilepaths、mode = wintway、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:inotifypropertychangeから派生したクラスのデータがツリーアイテムの表示に影響しないのはなぜですか。私は理解していますか:インターフェイスは、inotifypropertychangeを自動的に再描画しますか、またはこの操作を手動で実行する必要がありますか?現在、TreeViewItemsは更新されておらず、PropertyChamgedは常にnullです。イベントの加入者がプロパティルチャンジをしていないという感覚。
解決
設定する必要はありません NotifyOnTargetUpdated
.
代わりに、必ず上げてください PropertyChanged
イベント(適切なプロパティ名が渡されます PropertyChangedEventArgs
パスコレクションが更新されるたびに親エンティティでハンドラーに渡されるか、ナビゲーションプロパティにの実装をするたびに INotifyCollectionChanged
.
他のヒント
理由を見つけたと思います。フォルダーを絶えずスキャンする私の背景スレッドは、inotifyPropertyChangedから派生したデータクラスの新しいインスタンスを作成します。これは、TreeViewItems(itemsource)のソースとして機能します。この原則は、見つかったファイルのコレクションで何をすべきかを予測することが不可能であるため、選択されます。新しいアイテムを追加する、既存の既存のアイテムを削除するか、既存の編集を編集します。 ItemsSource Trickを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、このクラスにバインドすると、アイテムの追加、削除、または変更のみが期待されますが、データクラスの新しいインスタンスを項目に置き換えることはできません。