1

我有一个who设置为我拥有的模型TreeViewItemsSource3 级深是一个状态可以改变的对象,而不是为每个阶段(非常冗长的业务)编写一个 View 和 ViewModel,我只想使用代码来更新它。

所以基本上我有一个事件,一旦我的模型更新,我就会触发它,然后找到TreeViewItem与这些数据相关联的事件。我现在的问题是我不知道如何更新绑定以反映新值!

任何人都可以帮忙吗?

我知道这不是最佳实践,但我真的不想浪费时间编写大量代码来更新一件事。

谢谢克里斯

4

3 回答 3

2

您确定在相关类上实现 INotifyPropertyChanged 不会更容易吗?

于 2009-12-07T17:20:00.823 回答
0

听起来你可能需要看看UpdateSourceandUpdateTarget方法。

UpdateSource 的 MSDN 参考

虽然我不完全确定当您实际将 TreeView 绑定ItemSource到分层数据结构时这会起作用,但这是我将开始调查的地方。

于 2009-12-07T17:19:43.460 回答
0

这个例子有效,尽管它只有两层(不是三层)。它显示了一个简单的 2 级分层树视图,其中包含父项 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>

这是一个 hack,但每次它的 ItemsSource 属性更改时,它都会重新评估 DataTemplate。

理想情况下,您将在此 TreeViewItem 绑定到的模型对象类上实现 INotifyPropertyChanged,并在该值更改时触发 PropertyChanged 事件。事实上,您应该小心,因为它不会导致内存泄漏:Finding memory-leaks in WPF Applications

于 2009-12-07T17:22:32.847 回答