Frage

Ich habe eine TreeView dessen ItemsSource ist auf ein Modell ich habe. 3 Ebenen tief ist ein Objekt, dessen Zustand und ändern können, anstatt eine Ansicht und Ansichtsmodell für jede Stufe schreiben (sehr lange Geschäft) Ich wollte diese mit dem Code nur aktualisieren.

Also im Grunde ich eine Veranstaltung, die einmal mein Modell Updates abgefeuert wird, fange ich es dann die TreeViewItem mit diesem Bit an Daten gefunden. Mein Problem jetzt ist, ich habe keine Ahnung, wie die Bindung an sie aktualisieren den neuen Wert zu reflektieren!

Kann mir jemand helfen?

Ich weiß, das ist nicht die beste Praxis, aber ich mag wirklich nicht haben, Zeit mit dem Schreiben eine enorme Menge an Code zu verschwenden, um nur eine Sache zu aktualisieren.

Danke Chris

War es hilfreich?

Lösung

Dieses Beispiel funktioniert, obwohl es nur zwei (nicht 3) Ebenen tief ist. Es zeigt eine einfache 2-Ebene hierarchische Baumstruktur mit übergeordneten Elementen A, B und C, mit nummerierten Kindern (A.1, B.1, etc). Wenn das Umbenennen B.1 Schaltfläche geklickt wird, benennt es 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>

Dies ist ein Hack, aber es erneut wertet die Datatemplate jedes Mal, es Itemssource-Eigenschaft Änderungen ist.

Im Idealfall würden Sie INotifyPropertyChanged auf Ihrer Modellobjektklasse implementieren, dass dies TreeViewItem zu, gebunden ist, und haben sie das Property Ereignis ausgelöst, wenn die Wertänderungen. In der Tat, sollten Sie vorsichtig sein, dass Sie nicht ein Speicherleck werden entstehen, weil es nicht: Die Suche nach Speicherlecks in WPF-Anwendungen .

Andere Tipps

Sind Sie sicher, dass es nicht einfacher wäre, INotifyPropertyChanged auf der entsprechenden Klasse zu implementieren?

Klingt wie Sie einen Blick auf den UpdateSource und UpdateTarget Methoden zu nehmen brauchen könnten.

MSDN Referenz für Updates

Obwohl ich bin mir nicht ganz sicher, dass dies funktionieren wird, wenn Sie tatsächlich haben die TreeView des ItemSource zu einer hierarchischen Datenstruktur gebunden, aber es ist, wo ich die Untersuchung beginnen würde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top