简体   繁体   English

自定义WPF TreeView绑定

[英]Custom WPF TreeView Binding

I am trying to bind a collection of custom objects to a tree view's ItemSource in WPF with no success. 我试图将自定义对象的集合绑定到WPF中的树视图的ItemSource,但没有成功。

Here is the MainWindow.xaml: 这是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: 这是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: 这是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. 然后,该字符串列表将传递到WaferSelectionTreeViewViewModel类的构造函数中。

Here is the WaferSelectionTreeViewViewModel.cs: 这是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 凯尔

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: 如果从Visual Studio运行应用程序,则可能会在“ Output窗口中看到一条或多条这样的消息:

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. 首先,每个根项目都绑定到TreeViewViewModel.ProcessListProcess对象,并被告知显示一个名为ProcessNumber的属性,但是没有这样的属性,至少在您发布的代码中没有。 So I'm guessing the process items are showing up in the TreeView, but they're blank. 所以我猜的过程中项目显示在TreeView,但他们是空白。

Secondly, your HierarchicalItemTemplate says that the list of child items can be found in a property called ProcessList . 其次,您的HierarchicalItemTemplate说,子项列表可以在名为ProcessList的属性中找到。 But each root item is a Process , which doesn't have that property, so no child items are displayed. 但是每个根项都是一个Process ,它没有该属性,因此不会显示任何子项。 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). 现在, Process.Children是一个简单的string s列表,因此您无需包括<HierarchicalDataTemplate.ItemTemplate>部分(当然,字符串不具有模板要查找的Wafer属性)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM