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>

Q: INotifyPropertyChange から派生したクラスのデータがツリー アイテムの表示に影響しないのはなぜですか。INotifyPropertyChange インターフェイスは TreeViewItems を自動的に再描画しますか、それともこの操作を手動で実行する必要がありますか? 現在、TreeViewItems は更新されておらず、PropertyChamged は常に null です。イベント OnPropertyChanged のサブスクライバーがいないという感じ。

4

2 に答える 2

2

を設定する必要はありませんNotifyOnTargetUpdated

代わりに、パス コレクションが更新されるたびに親エンティティでPropertyChanged(適切なプロパティ名をハンドラーに渡して) イベントを発生させるか、ナビゲーション プロパティを の実装にするようにしてください。PropertyChangedEventArgsINotifyCollectionChanged

于 2010-12-26T07:47:32.670 に答える
0

理由が分かった気がします。フォルダーを常にスキャンするバックグラウンド スレッドは、INotifyPropertyChanged から派生したデータ クラスの新しいインスタンスを作成します。これは、TreeViewItems (ItemsSource) のソースとして機能します。この原則が選択されているのは、見つかったファイルのコレクションに対して何をすべきかを予測できないためです。つまり、新しいアイテムを追加するか、既存のものを削除するか、既存のものを編集します。私がItemsSourceトリックをPropertyChangeで置き換えるつもりだったとしても、うまくいきません。したがって、私にとって唯一の解決策は、TreeViewItems の別の (バックグラウンド、スキャンフォルダー) スレッド Refresh() メソッドから呼び出すことでした。

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 に答える