我创建了一个包含TreeView和ListBox的UserControl,并公开了ItemsSource依赖项属性,以便UserControl的客户端可以设置底层TreeView的ItemsSource属性:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<HierarchicalDataTemplate DataType="{x:Type l:LocationViewModel}" ItemsSource="{Binding Path=Children}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<TabControl>
<TabItem Header="Tab 1">
<l:HierarchicalSelectionControl x:Name="control1" ItemsSource="{Binding Path=LocationViewModels}" />
</TabItem>
<TabItem Header="Tab 2">
<l:HierarchicalSelectionControl x:Name="control2" ItemsSource="{Binding Path=LocationViewModels}" />
</TabItem>
</TabControl>
</Grid>
在上面的示例中,我有两个选项卡,每个选项卡都有一个UserControl实例,绑定到同一个集合。树仅显示所选选项卡(在本例中为选项卡1)。当我切换到Tab 2时,TreeView不显示。如果我将Tab 2设置为选定的选项卡,则反之亦然。这是我的UserControl片段:
<UserControl x:Class="WpfApplication1.HierarchicalSelectionControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:l="clr-namespace:WpfApplication1"
x:Name="root">
...
<TreeView Name="_trvAvailableLocations" ItemsSource="{Binding ItemsSource, ElementName=root}" />
...
这是代码隐藏代码段:
public partial class HierarchicalSelectionControl : UserControl
{
public HierarchicalSelectionControl()
{
InitializeComponent();
}
/// <summary>
/// ItemsSource Dependency Property.
/// </summary>
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IList), typeof(HierarchicalSelectionControl));
/// <summary>
/// Gets or sets the items source.
/// </summary>
/// <value>The items source.</value>
public IList ItemsSource
{
get { return (IList)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
...
}
这是LocationViewModel定义:
public class LocationViewModel : INotifyPropertyChanged
{
#region INotifyPropertyChanged members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#endregion
private Location _location;
private bool _isSelected;
private bool _isExpanded;
private ObservableCollection<LocationViewModel> _childLocations;
/// <summary>
/// Initializes the view model.
/// </summary>
/// <param name="location">The actual Location wrapped by this view model.</param>
public LocationViewModel(Location location)
{
if (location == null)
{
throw new ArgumentNullException("location");
}
_location = location;
}
/// <summary>
/// Gets or sets whether the TreeViewItem associated with this
/// LocationViewModel is selected.
/// </summary>
public bool IsSelected
{
get { return _isSelected; }
set
{
if (value != _isSelected)
{
_isSelected = value;
OnPropertyChanged("IsSelected");
}
}
}
/// <summary>
/// Gets or sets whether the TreeViewItem associated with this
/// LocationViewModel is expanded.
/// </summary>
public bool IsExpanded
{
get { return _isExpanded; }
set
{
if (value != _isExpanded)
{
_isExpanded = value;
OnPropertyChanged("IsExpanded");
}
}
}
/// <summary>
/// Gets the name of the location.
/// </summary>
public string Name
{
get { return _location.Name; }
}
/// <summary>
/// Gets the child location view models.
/// </summary>
public ObservableCollection<LocationViewModel> Children
{
get
{
if (_childLocations == null)
{
_childLocations = new ObservableCollection<LocationViewModel>();
_childLocations.Add(new LocationViewModel(new Location { Name = string.Format("{0} child", Name) }));
}
return _childLocations;
}
}
}
我必须对依赖项属性做错了,因为如果我只是在每个TabItem中放置一个TreeView,并将TreeView ItemsSource绑定到底层集合,则会显示两个TreeView。但是从UserControl中暴露出来,TreeView仅显示初始可见的TabItem。有人可以指出我做错了吗?
提前致谢!