自定义WPF TreeView绑定

时间:2014-09-30 17:21:01

标签: c# wpf data-binding treeview wpf-controls

我正在尝试将自定义对象的集合绑定到WPF中的树视图的ItemSource,但没有成功。

这是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>

这是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>

这是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");
        }
    }
}

仅供参考,这行代码......

e.Result = new SingulationOneTable().GetWaferList();

...只返回一大串字符串。然后将该字符串列表传递给WaferSelectionTreeViewViewModel类的构造函数。

这是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");
        }
    }
}

任何人都可以找出为什么这些项目没有出现在树视图中吗?

此致

凯尔

1 个答案:

答案 0 :(得分:0)

绑定中有一些错误。如果从Visual Studio运行应用程序,您可能会在Output窗口中看到一条或多条这样的消息:

System.Windows.Data Error: 40 : BindingExpression path error: (...)

首先,每个根项都绑定到Process的{​​{1}}对象,并告诉它显示一个名为TreeViewViewModel.ProcessList的属性,但是没有这样的属性,至少在您发布的代码。所以我猜测 过程项在TreeView中显示,但它们是空白的。

其次,您的ProcessNumber表示可以在名为HierarchicalItemTemplate的属性中找到子项列表。但是每个根项都是ProcessList,它没有该属性,因此不会显示任何子项。你可能意味着:

Process

现在,<HierarchicalDataTemplate ItemsSource="{Binding Children}"> Process.Children的简单列表,因此您不需要包含string部分(当然,字符串没有<HierarchicalDataTemplate.ItemTemplate>部分1}}模板正在寻找的属性。