다음 코드는 CompoundObject에 대한 계층 적 컬렉션을로드 한 다음 문자열에 대한 계층 적 컬렉션을로드합니다. 하지만 안타깝게도 아래쪽에있는 문자열 대신에 문자열의 맨 위에 문자열을 삽입합니다. (항상 보았던 동작입니다.)TreeView 및 복합 데이터에 이상한 동작이 없음
나는 열거 자, 알 고리 자 등의 순서를 변경하려고 시도했습니다. 동일한 결과를 생성합니다. 나는 (스레드에서 동일한 코드를 사용하여) 정상 보이는 목록을로드하는 사전했습니다.
어떤 아이디어 일이 뭐죠?
CompoundObject.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
namespace ComplexTreeViewLazyLoadingTest
{
public class CompoundObject : IEnumerable<object>, INotifyCollectionChanged
{
public string Name { get; set; }
public ObservableCollection<CompoundObject> objects { get; private set; }
public ObservableCollection<string> Items { get; private set; }
void OnChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (CollectionChanged != null)
App.Current.Dispatcher.Invoke((Action<object, NotifyCollectionChangedEventArgs>)((senderr, ee) => {
CollectionChanged(senderr, ee);
}), sender, e);
}
public CompoundObject(string name)
{
Name = name;
Items = new ObservableCollection<string>();
objects = new ObservableCollection<CompoundObject>();
Items.CollectionChanged += new NotifyCollectionChangedEventHandler(OnChanged);
objects.CollectionChanged += new NotifyCollectionChangedEventHandler(OnChanged);
}
public IEnumerator<object> GetEnumerator()
{
if (objects != null) foreach(var a in objects) yield return a;
if (Items != null) foreach (var a in Items) yield return a;
yield break;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); }
public event NotifyCollectionChangedEventHandler CollectionChanged;
}
}
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
namespace ComplexTreeViewLazyLoadingTest
{
public partial class MainWindow : Window
{
CompoundObject c = new CompoundObject("Root");
public MainWindow()
{
InitializeComponent();
treeView.DataContext = c;
treeView.ItemsSource = c;
ThreadPool.QueueUserWorkItem(new WaitCallback(Update));
}
void Update(object data)
{
for (int i = 0; i < 10; i++)
{
Application.Current.Dispatcher.Invoke((Action<CompoundObject>)((cc) => {
c.objects.Add(cc);
}), new CompoundObject("Object " + i));
for (int j = 0; j < 5; j++)
{
Thread.Sleep(100);
Application.Current.Dispatcher.Invoke((Action<CompoundObject>)((cc) =>
{
c.objects[i].objects.Add(cc);
}), new CompoundObject("subObject " + j));
}
}
for (int i = 0; i < 8; i++)
{
Thread.Sleep(250);
Application.Current.Dispatcher.Invoke((Action<string>)((ii) =>
{
c.Items.Add("Item " + ii);
}), i.ToString());
}
}
} // MainWindow
public class DTS : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
if (element != null && item != null)
{
if (item is CompoundObject)
{
return element.FindResource("CompoundTemplate") as DataTemplate;
}
if (item is int)
{
return element.FindResource("DefaultTemplate") as DataTemplate;
}
}
return null;
}
}
}
MainWindow.xaml
<Window x:Class="ComplexTreeViewLazyLoadingTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ComplexTreeViewLazyLoadingTest;assembly="
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:DTS x:Key="DTS"/>
<HierarchicalDataTemplate x:Key="CompoundTemplate" ItemsSource="{Binding Path=.}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="DefaultTemplate" ItemsSource="{Binding Path=.}">
<TextBlock Text="{Binding Path=.}" Background="Aqua" />
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<TreeView Name="treeView" ItemTemplateSelector="{StaticResource DTS}"/>
</Grid>
</Window>
감사 100 % 확신하지 말라. 나는 네가 한 일을 말하는 것이지 어떻게 든 나는 그 말을 너의 대답으로 고쳤다. NotifyCollectionChangedEventArgs에는 항목을 추가 할 색인이 전달됩니다. 하위 컬렉션은 서로에 대해 알고 있기 때문에 둘 다 동일한 시작 인덱스를 전달합니다. 추가 된 요소와 함께 내 자신의 NotifyCollectionChangedEventArgs를 전달하고 NewStartIndex = -1은 항상 목록의 맨 아래에 추가합니다. – AbstractDissonance
특정 상황에서이 방법이 효과가있는 것처럼 들리지만 NotifyCollectionChanged에 대한 모든 사례를 올바르게 구현하여 '조합 된'컬렉션보기를 제공하는 것이 좋습니다. 내가 올바르게 이해하면 현재 구현은 항상 목록의 끝에 추가하는 경우에만 작동합니다. –