自定义WPF树视图绑定

本文关键字:绑定 视图 WPF 自定义 | 更新日期: 2023-09-27 18:25:10

我试图在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();

只是返回一个大的字符串列表。然后,该字符串列表被传递到WaferSelectionTreeViewModel类的构造函数中。

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

有人能弄清楚为什么这些项目没有显示在树视图中吗??

问候,

Kyle

自定义WPF树视图绑定

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

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

首先,每个根项都绑定到来自TreeViewViewModel.ProcessListProcess对象,并被告知显示一个名为ProcessNumber的属性,但没有这样的属性,至少在您发布的代码中没有。所以我猜流程项显示在TreeView中,但它们是空白的。

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

<HierarchicalDataTemplate ItemsSource="{Binding Children}">

现在,Process.Childrenstring的一个简单列表,所以您不需要包括<HierarchicalDataTemplate.ItemTemplate>部分(当然,字符串没有模板所要查找的Wafer属性)。