绑定到TabItem中的UserControl ItemsSource DependencyProperty

时间:2011-07-28 17:20:44

标签: wpf dependency-properties

我创建了一个包含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。有人可以指出我做错了吗?

提前致谢!

0 个答案:

没有答案