Причина, по которой имя dataGrid
не может быть найдено, заключается в том, что вы пытаетесь получить доступ к элементу, расположенному в другой области имен , что означает, что элементы в шаблоне данных не могут "видеть" элементы которые находятся за пределами этого шаблона.
Чтобы исправить это, вы можете сделать следующее. Вам понадобится другая модель представления для вашего UserControl
(или Window
, независимо от того, что содержит вас TreeView
и DataGrid
). Давайте назовем это MyTreeViewModel
:
public class MyTreeViewModel : INotifyPropertyChanged // Better to implement this interface in some base class for all your view models
{
private TreeItemViewModelBase _selectedNode;
public IEnumerable<TreeItemViewModelBase> TopLevelNodes
{
get { yield return new TopLevelTreeNodeViewModel(); // Subclass of your base class for tree nodes (ViewModelBase) }
}
public TreeItemViewModelBase SelectedNode
{
get { return _selectedNode; }
set
{
_selectedNode = value;
RaisePropertyChanged("SelectedNode");
}
}
}
Установите экземпляр этой модели представления как DataContext
вашего UserControl
, который содержит вас TreeView
и DataGrid
. Тогда ваш XAML будет выглядеть так:
<DataGrid Name="dataGrid" ItemsSource="{Binding SelectedNode.GridData}" />
<TreeView Name="treeView" ItemsSource="{Binding TopLevelNodes}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type ViewModel:ViewModelBase}" ItemsSource="{Binding Nodes}">
<TextBlock Text="{Binding Header}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
Затем вам нужно изменить ViewModelBase (я предлагаю переименовать его в TreeItemViewModelBase
, чтобы избежать путаницы):
public abstract class TreeItemViewModelBase : INotifyPropertyChanged
{
private bool _isSelected;
public TreeItemViewModelBase(MyTreeViewModel parentViewModel)
{
ParentViewModel = parentViewModel;
}
public abstract string Header { get; }
public abstract IEnumerable<TreeItemViewModelBase> Nodes { get; }
public abstract IEnumerable GridData { get; }
public MyTreeViewModel ParentViewModel { get; private set; }
// following are hooked up to PropertyChanged event in the standard way
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
RaisePropertyChanged("IsSelected");
if (_isSelected) {
ParentViewModel.SelectedNode = this;
}
}
}
public bool IsExpanded { get; set; }
}
Как вы видите, он поддерживает ссылку на модель родительского представления и всякий раз, когда для IsSelected
установлено значение true
, он устанавливает себя как SelectedNode
в модели родительского представления, что вызывает привязку данных к DataGrid
s ItemsSource
чтобы обновить.
Надеюсь, это поможет.