Reputation: 1933
I am trying to bind a collection of custom objects to a tree view's ItemSource in WPF with no success.
Here is the MainWindow.xaml:
<Window
x:Class="AoiImageLift.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:AoiImageLift.UI.ViewModels"
Height="500"
Width="500">
<Window.DataContext>
<vm:MainWindowViewModel/>
</Window.DataContext>
<TreeView ItemsSource="{Binding TreeViewViewModel.ProcessList}"/>
</Window>
Here is the App.xaml:
</Application>
</Application.Resources>
<!-- TreeView Style -->
<Style TargetType="{x:Type TreeView}">
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Visible"/>
<Setter Property="SelectedValuePath" Value="Wafer"/>
<Setter Property="ItemTemplate">
<Setter.Value>
<HierarchicalDataTemplate ItemsSource="{Binding ProcessList}">
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate>
<TextBlock
FontFamily="SegoeUI"
Foreground="MidnightBlue"
Text="{Binding Wafer}"/>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
<TextBlock
Text="{Binding ProcessNumber}"
FontFamily="SegoeUI"
Foreground="MidnightBlue"/>
</HierarchicalDataTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>
Here is the MainWindowViewModel.cs:
public class MainWindowViewModel : ViewModel
{
private WaferSelectionTreeViewViewModel treeViewViewModel;
public MainWindowViewModel()
{
BackgroundWorker initThread = new BackgroundWorker();
initThread.DoWork += (sender, e) =>
{
e.Result = new SingulationOneTable().GetWaferList();
};
initThread.RunWorkerCompleted += (sender, e) =>
{
TreeViewViewModel = new WaferSelectionTreeViewViewModel(
(List<string>) e.Result);
};
initThread.RunWorkerAsync();
}
public WaferSelectionTreeViewViewModel TreeViewViewModel
{
get { return treeViewViewModel; }
set
{
treeViewViewModel = value;
OnPropertyChanged("TreeViewViewModel");
}
}
}
FYI, this line of code...
e.Result = new SingulationOneTable().GetWaferList();
...simply returns a large list of strings. That list of strings is then passed into the constructor of the WaferSelectionTreeViewViewModel class.
Here is the WaferSelectionTreeViewViewModel.cs:
public class WaferSelectionTreeViewViewModel : ViewModel
{
private ObservableCollection<Process> processList;
public class TreeViewItemBase : ViewModel
{
private bool isSelected;
public bool IsSelected
{
get { return isSelected; }
set
{
if (value != isSelected)
{
isSelected = value;
OnPropertyChanged("IsSelected");
}
}
}
private bool isExpanded;
public bool IsExpanded
{
get { return isExpanded; }
set
{
if (value != isExpanded)
{
isExpanded = value;
OnPropertyChanged("IsExpanded");
}
}
}
}
public class Process : TreeViewItemBase
{
private string name;
public Process(string name)
{
this.name = name;
this.Children = new ObservableCollection<string>();
}
public string Name { get { return name; } }
public ObservableCollection<string> Children { get; set; }
}
public WaferSelectionTreeViewViewModel(List<string> waferList)
{
processList = new ObservableCollection<Process>();
List<string> procList = new List<string>();
foreach (string wafer in waferList)
{
procList.Add(wafer.Substring(0, 4));
}
IEnumerable<string> distintProcessList = procList.Distinct();
foreach (string process in distintProcessList)
{
Process newProcess = new Process(process);
List<string> wafersInProcess = waferList.FindAll(
x => x.Substring(0, 4) == process);
foreach (string waferInThisProcess in wafersInProcess)
{
newProcess.Children.Add(waferInThisProcess);
}
}
}
public ObservableCollection<Process> ProcessList
{
get
{
return processList;
}
set
{
processList = value;
OnPropertyChanged("ProcessList");
}
}
}
Can anyone figure out why the items are not showing up in the tree view??
Regards,
Kyle
Upvotes: 0
Views: 474
Reputation: 13057
There are a couple of errors in your bindings. If you run your application from Visual Studio, you'll probably see one or more messages like this in the Output
window:
System.Windows.Data Error: 40 : BindingExpression path error: (...)
Firstly, each root item is bound to a Process
object from TreeViewViewModel.ProcessList
and it's told to display a property called ProcessNumber
, but there is no such property, at least not in the code you posted. So I'm guessing the process items are showing up in the TreeView, but they're blank.
Secondly, your HierarchicalItemTemplate
says that the list of child items can be found in a property called ProcessList
. But each root item is a Process
, which doesn't have that property, so no child items are displayed. You probably mean:
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
Now, Process.Children
is a simple list of string
s, so you don't need to include the <HierarchicalDataTemplate.ItemTemplate>
part (and of course, strings don't have the Wafer
property that template is looking for).
Upvotes: 1