Как автоматически обновляться WPF TreeViewItems с значениями на основе свойств .NET класса?

StackOverflow https://stackoverflow.com/questions/4533107

Вопрос

Доброе утро. У меня есть класс с данными, полученными из INOTIFYPROPERTYCHANGE. Данные поступают из фонового потока, который ищет файлы с определенным расширением в определенных местах. Общественная собственность класса реагирует на событие на PropertyChange, обновляя данные в отдельном потоке. Кроме того, в XAML Treeview описано на основе HierarhicalDatatemplates. Каждый текстовый блок внутри шаблонов поставляется itemssource = "{Binding FordfilePaths, 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 всегда NULL. Ощущение, что нет подписчиков на мероприятие на пропертизации.

Это было полезно?

Решение

Вам не нужно устанавливать NotifyOnTargetUpdated.

Вместо этого обязательно поднимите PropertyChanged событие (с соответствующим именем имуществом прошло с PropertyChangedEventArgs Передается в обработчик) на родительском объекте каждый раз, когда обновляется коллекция Paths, или навигационное свойство будет реализацией INotifyCollectionChanged.

Другие советы

Я думаю, что нашел причину. Мой фоновый поток, который постоянно сканирует папку, создает новый экземпляр класса данных, полученный из inotifypropertychanged, который служит источником для TreeViewItems (itemsSource). Этот принцип выбран, потому что невозможно предсказать, что следует сделать с помощью коллекции найденных файлов: добавить новый элемент, удалить существующий или редактировать существующее. Если я когда -нибудь намеревался заменить трюк ItemsSource на 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();
}

Использование этой ситуации с этими классами унаследовано от INOTIFYPORPERTYCHANGED. Itemscontrol, вы привязываетесь к этому классу, ожидается только добавить, удалить или изменять элементы, но не заменить элементы, которые смотрят новый экземпляр класса данных.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top