문제

나는있다 TreeView 누구 ItemsSource 내가 가진 모델로 설정됩니다. 3 레벨 깊은 곳은 상태가 변경 될 수있는 객체이며 각 단계 (매우 긴 비즈니스)에 대한보기와 뷰 모델을 작성하기보다는 코드를 사용하여 업데이트하고 싶었습니다.

그래서 기본적으로 모델 업데이트가 끝나면 해고 된 이벤트가 있습니다. TreeViewItem 이 데이터와 관련이 있습니다. 내 문제는 이제 새로운 가치를 반영하기 위해 바인딩을 업데이트하는 방법에 대해 전혀 모른다는 것입니다!

누구든지 도울 수 있습니까?

나는 이것이 모범 사례가 아니라는 것을 알고 있지만 한 가지만 업데이트하기 위해 엄청난 양의 코드를 작성하는 데 시간을 낭비하고 싶지 않습니다.

감사합니다 Chris

도움이 되었습니까?

해결책

이 예제는 작동하지만 두 가지 (3이 아님) 깊이에 불과합니다. 부모 항목 A, B 및 C가있는 간단한 2 단계 계층 적 트리 뷰를 보여줍니다 (A.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>

이것은 해킹이지만 항목 소스 속성 변경 될 때마다 데이터 emplate을 다시 평가합니다.

이상적으로, 당신은이 treeviewitem이 묶여있는 모델 객체 클래스에서 inotifypropertychanged를 구현하고, 그 값이 변경 될 때 속성 교환 이벤트를 발사하도록합니다. 사실, 메모리 누출이 발생하지 않도록주의해야합니다. WPF 응용 프로그램에서 메모리 누출을 찾습니다.

다른 팁

관련 클래스에서 inotifyPropertyChanged를 구현하는 것이 더 쉽지 않다고 확신합니까?

당신이 UpdateSource 그리고 UpdateTarget 행동 양식.

updateSource에 대한 MSDN 참조

실제로 TreeView의 묶을 때 이것이 효과가 있을지 확실하지는 않지만 ItemSource 계층 적 데이터 구조에 대해서는 조사를 시작하는 곳입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top