wpf - 在用户控件中绑定 ObservableCollection 依赖属性
问题描述
我有一个承载 TreeView 的 UserControl,该 TreeView 具有从自定义类的 ObservableCollection 继承的自定义集合。我正在尝试使用 ViewModel 中的依赖属性绑定到一个属性,而我已经证明该过程适用于另一个在此处不起作用的属性。
我确定这是我错过的一些愚蠢的事情,但我一直在转圈,有人能发现我的错误吗?
用户控件 XAML:
<UserControl
x:Class="FileExplorer.TreeViewUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:fe="clr-namespace:WpfControlLibrary.FileExplorer"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="FileExplorer"
d:DesignHeight="300"
d:DesignWidth="400"
mc:Ignorable="d">
<TreeView
BorderThickness="0"
ItemsSource="{Binding FileSystem, RelativeSource={RelativeSource AncestorType=UserControl}}"
TreeViewItem.Collapsed="TreeView_Collapsed"
TreeViewItem.Expanded="TreeView_Expanded"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type fe:FileSystemObject}" ItemsSource="{Binding Items}">
<StackPanel Margin="0,2" Orientation="Horizontal">
<Image
Width="14"
Margin="2"
Source="{Binding Image}"
Stretch="Fill" />
<TextBlock
VerticalAlignment="Center"
FontSize="{StaticResource FontSizeSmall}"
Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
UserControl 背后的代码:
Namespace FileExplorer
Public Class TreeViewUserControl
Inherits UserControl
#Region "Constructors"
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.DataContext = Me
End Sub
#End Region
#Region "Properties"
Public Shared ReadOnly FileSystemProperty As DependencyProperty = DependencyProperty.Register("FileSystem", GetType(FileSystemObjectCollection), GetType(TreeViewUserControl))
Public Property FileSystem As FileSystemObjectCollection
Get
Return CType(GetValue(FileSystemProperty), FileSystemObjectCollection)
End Get
Set(ByVal value As FileSystemObjectCollection)
SetValue(FileSystemProperty, value)
FileExplorer.UpdateLayout()
End Set
End Property
#End Region
Private Function GetFileSystemInfo(ByVal root As String) As FileSystemObjectCollection
Dim items As New FileSystemObjectCollection
' Parse all the directories at the path
For Each dir As String In Directory.GetDirectories(root)
items.Add(New FileSystemObject(dir, root))
Next
' Parse all the file at the path
For Each file As String In Directory.GetFiles(root)
items.Add(New FileSystemObject(file, root))
Next
Return items
End Function
Private Sub TreeView_Collapsed(sender As Object, e As RoutedEventArgs)
Dim node As TreeViewItem = CType(e.OriginalSource, TreeViewItem)
Dim fs As FileSystemObject = CType(node.DataContext, FileSystemObject)
fs.Clear()
End Sub
Private Sub TreeView_Expanded(sender As Object, e As RoutedEventArgs)
Dim node As TreeViewItem = CType(e.OriginalSource, TreeViewItem)
Dim fs As FileSystemObject = CType(node.DataContext, FileSystemObject)
If Not fs.HasChildren Then Exit Sub
fs.Items = GetFileSystemInfo(fs.FullName)
End Sub
End Class
End Namespace
主窗口 XAML:
<Window
x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:fe="clr-namespace:WpfControlLibrary.FileExplorer;assembly=WpfControlLibrary"
xmlns:local="clr-namespace:ModStudio.Client"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:ModStudio.Client.ViewModels"
Title="MainWindow"
d:DesignHeight="600"
d:DesignWidth="800"
WindowStartupLocation="CenterOwner"
WindowState="Maximized"
mc:Ignorable="d">
<Window.Resources>
<vm:MainWindowViewModel x:Key="MainWindowViewModel" />
</Window.Resources>
<Grid>
<fe:TreeViewUserControl DataContext="{StaticResource MainWindowViewModel}" FileSystem="{Binding ApplicationExplorer}" />
</Grid>
</Window>
在后面的代码中将MainWindow
其DataContext
设置为 ViewModel 的新实例。MainWindowViewModel
有一个名为的属性,ApplicationExplorer
它是 的一个实例FileSystemObjectCollection
。如前所述FileSystemObjectCollection
,继承自ObservableCollection(Of FileSystemObject)
. AFileSystemObject
实现INotifyPropertyChanged
。如果我更改ApplicationExplorer
属性,控件将保持空白。
我在这里故意省略了一些代码,但如果需要可以添加它们。
解决方案
不要在DataContext
中设置UserControl
,即删除此行:
Me.DataContext = Me
当你明确地设置DataContext
这样的,你打破了继承链,这意味着绑定到ApplicationExplorer
你的窗口中的属性不再起作用:
<fe:TreeViewUserControl DataContext="{StaticResource MainWindowViewModel}"
FileSystem="{Binding ApplicationExplorer}" />
推荐阅读
- azure-devops - Azure Devops YML 模板条件和依赖项
- java - Java中私有Map成员的访问方法
- kubernetes-helm - 调用 tpl 时出现错误错误:在安装 helm chart 时为“environment.yaml”未关闭操作执行 tpl 函数期间出错
- azure-ad-b2c - B2C 的 SSPR 密码策略是什么?
- flutter - Flutter - 出现键盘时出现底部溢出问题
- swift - 使用 Alamofire 和 SwifrtJSON 以及完成处理程序(@escaping)在 tableview 中解析和映射数据
- html - HTML/CSS 多行单选按钮
- r - 如何根据时间块创建唯一索引
- javascript - WordPress elementor 项目
- sql - 您可以通过多列在 SQL 2 表中进行 INNER JOIN 吗?