Обновить привязку TreeViewItem с помощью кода? (XAML / WPF) - PullRequest
1 голос
/ 07 декабря 2009

У меня есть TreeView, для которого ItemsSource соответствует модели, которую я имею. 3 уровня глубины - это объект, состояние которого может меняться, и вместо того, чтобы писать View и ViewModel для каждого этапа (очень длительный бизнес), я хотел просто обновить это, используя код.

Таким образом, в основном, у меня происходит событие, которое запускается после обновления моей модели, я ловлю его и нахожу TreeViewItem, связанный с этим битом данных. Моя проблема сейчас в том, что я не знаю, как обновить привязку, чтобы она отражала новое значение!

Может кто-нибудь помочь?

Я знаю, что это не лучшая практика, но я действительно не хочу тратить время на написание огромного количества кода, чтобы просто обновить одну вещь.

Спасибо Chris

Ответы [ 3 ]

2 голосов
/ 07 декабря 2009

Вы уверены, что не будет проще реализовать INotifyPropertyChanged для соответствующего класса?

0 голосов
/ 07 декабря 2009

Этот пример работает, хотя в нем всего два (а не 3) уровня. Он показывает простое двухуровневое иерархическое древовидное представление с родительскими элементами A, B и C с пронумерованными дочерними элементами (A.1, B.1 и т. Д.). При нажатии кнопки «Переименовать B.1» B.1 переименовывается в «Sylvia».

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace UpdateVanillaBindingValue
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private DataClass _data;

        public Window1()
        {
            InitializeComponent();
            var data = CreateData();
            DataContext = _data = data;
        }

        private DataClass CreateData()
        {
            return new DataClass
               {
                   Parents=new List<Parent>
                       {
                           new Parent{Name="A",Children=new List<Child>{new Child{Name="A.0"},new Child{Name="A.1"}}},
                           new Parent{Name="B",Children=new List<Child>{new Child{Name="B.0"},new Child{Name="B.1"},new Child{Name="B.2"}}},
                           new Parent{Name="C",Children=new List<Child>{new Child{Name="C.0"},new Child{Name="C.1"}}}
                       }
               };
        }

        private void Rename_Click(object sender, RoutedEventArgs e)
        {
            var parentB = _data.Parents[1];
            var parentBItem = TheTree.ItemContainerGenerator.ContainerFromItem(parentB) as TreeViewItem;
            parentB.Children[1].Name = "Sylvia";

            var parentBItemsSource = parentBItem.ItemsSource;
            parentBItem.ItemsSource = null;
            parentBItem.ItemsSource = parentBItemsSource;
        }
    }

    public class DataClass
    {
        public List<Parent> Parents { get; set; }
    }

    public class Parent
    {
        public string Name { get; set; }
        public List<Child> Children { get; set; }
    }

    public class Child
    {
        public string Name { get; set; }
    }
}

<Window x:Class="UpdateVanillaBindingValue.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <Grid.Resources>
            <DataTemplate x:Key="ChildTemplate">
                <TextBlock Margin="50,0,0,0" Text="{Binding Name}" />
            </DataTemplate>
            <HierarchicalDataTemplate x:Key="ParentTemplate" ItemsSource="{Binding Children}" ItemTemplate="{StaticResource ChildTemplate}">
                <TextBlock Text="{Binding Name}" />
            </HierarchicalDataTemplate>
        </Grid.Resources>
        <TreeView x:Name="TheTree" ItemsSource="{Binding Parents}" ItemTemplate="{StaticResource ParentTemplate}" />
        <Button VerticalAlignment="Bottom" HorizontalAlignment="Center" Content="Rename B.1" Click="Rename_Click" />
    </Grid>
</Window>

Это хак, но он переоценивает DataTemplate каждый раз, когда изменяется его свойство ItemsSource.

В идеале вы должны реализовать INotifyPropertyChanged в своем классе объектов модели, с которым связан этот TreeViewItem, и заставить его запускать событие PropertyChanged при изменении этого значения. На самом деле, вы должны быть осторожны, чтобы не вызвать утечку памяти, поскольку она не: Обнаружение утечек памяти в приложениях WPF .

0 голосов
/ 07 декабря 2009

Похоже, вам, возможно, придется взглянуть на методы UpdateSource и UpdateTarget.

Ссылка MSDN для UpdateSource

Хотя я не совсем уверен, что это сработает, когда вы на самом деле связали TreeView ItemSource с иерархической структурой данных, но именно здесь я бы начал исследовать.

...