Jeg har prøve at lave et lidt forsimplet eksempel på din kode, som har nogle af idéerne til hvordan det skal gøres, men der er stadig nogle ting der trænger til at blive tweaket, som f.eks. har jeg kun én kategori her, og jeg har ikke lavet nogen implementation for filtrering af disse, samt at når filteret skiftes, så tømmer jeg listerne og fylder dem igen, i stedet for blot at redigere forskellen, men her er "the basic idea", og så må du sige til hvis der skal mere til derfra. :)
DTO KLASSER:
public class Category
{
private JobFilter _jobFilter;
public string Name { get; set; }
public System.Collections.ObjectModel.ObservableCollection<Company> Companies { get; set; }
public System.Collections.ObjectModel.ObservableCollection<Company> FilteredCompanies { get; set; }
public Category(JobFilter jobFilter)
{
_jobFilter = jobFilter;
this.Companies = new System.Collections.ObjectModel.ObservableCollection<Company>();
this.FilteredCompanies = new System.Collections.ObjectModel.ObservableCollection<Company>();
this.Companies.CollectionChanged += Companies_CollectionChanged;
_jobFilter.FilterChanged += jobFilter_FilterChanged;
}
void Companies_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
RefreshFiltered();
}
void jobFilter_FilterChanged(object sender, System.EventArgs e)
{
RefreshFiltered();
}
private void RefreshFiltered()
{
this.FilteredCompanies.Clear();
foreach (Company company in this.Companies)
{
if (company.RefreshFilteredJobs(_jobFilter.Filter))
{
this.FilteredCompanies.Add(company);
}
}
}
}
public class Company
{
public string Name { get; set; }
public System.Collections.ObjectModel.ObservableCollection<Job> Jobs { get; set; }
public System.Collections.ObjectModel.ObservableCollection<Job> FilteredJobs { get; set; }
public Company()
{
this.Jobs = new System.Collections.ObjectModel.ObservableCollection<Job>();
this.FilteredJobs = new System.Collections.ObjectModel.ObservableCollection<Job>();
}
public bool RefreshFilteredJobs(string filter)
{
bool includeThis = false;
this.FilteredJobs.Clear();
foreach (Job job in this.Jobs.Where(e => e.Name.Contains(filter)))
{
this.FilteredJobs.Add(job);
includeThis = true;
}
return includeThis;
}
}
public class Job
{
public string Name { get; set; }
}
FILTER KLASSE:
public class JobFilter
{
public event System.EventHandler FilterChanged;
private string _filter;
public string Filter
{
get
{
return _filter;
}
set
{
SetFilter(value);
}
}
public JobFilter(string initialFilter = "")
{
SetFilter(initialFilter, notify: false);
}
private void SetFilter(string filter, bool notify = true)
{
_filter = filter ?? "";
if (notify && this.FilterChanged != null)
{
this.FilterChanged(this, System.EventArgs.Empty);
}
}
}
UI KODE:
public partial class MainWindow : Window
{
private JobFilter _jobFilter = new JobFilter();
public MainWindow()
{
InitializeComponent();
var category = new Category(_jobFilter) { Name = "Category 1" };
var comp1 = new Company { Name = "Company 1" };
comp1.Jobs.Add(new Job { Name = "Job 1.1" });
comp1.Jobs.Add(new Job { Name = "Job 1.2" });
category.Companies.Add(comp1);
var comp2 = new Company { Name = "Company 2" };
comp2.Jobs.Add(new Job { Name = "Job 2.1" });
comp2.Jobs.Add(new Job { Name = "Job 2.2" });
comp2.Jobs.Add(new Job { Name = "Job 2.3" });
category.Companies.Add(comp2);
var comp3 = new Company { Name = "Company 3" };
comp3.Jobs.Add(new Job { Name = "Job 3.1" });
comp3.Jobs.Add(new Job { Name = "Job 3.2" });
category.Companies.Add(comp3);
var source = new System.Collections.ObjectModel.ObservableCollection<Category>();
source.Add(category);
this.TreeView.ItemsSource = source;
}
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
_jobFilter.Filter = this.textBox1.Text;
}
}
<Window x:Class="WpfApplication1.MainWindow" xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Category}" ItemsSource="{Binding Path=FilteredCompanies}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Company}" ItemsSource="{Binding Path=FilteredJobs}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Job}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</Grid.Resources>
<TreeView Height="287" HorizontalAlignment="Left" Margin="12,12,0,0" Name="TreeView" VerticalAlignment="Top" Width="247" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="293,37,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" TextChanged="textBox1_TextChanged" />
</Grid>
</Window>