Привязка к UserControl ItemsSource DependencyProperty в элементе TabItem - PullRequest
0 голосов
/ 28 июля 2011

Я создал UserControl, содержащий TreeView и ListBox, и открыл свойство зависимостей ItemsSource, чтобы клиент UserControl мог установить свойство ItemsSource базового TreeView:

<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). Когда я переключаюсь на вкладку 2, TreeView не отображается. Если я выберу вкладку 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;
        }
    }
}

Я, должно быть, сделал что-то не так со свойством зависимости, потому что, если я просто добавлю TreeView в каждый элемент TabItem и свяжу TreeS ItemsSource с базовой коллекцией, отобразятся оба TreeView. Но представленный из UserControl, TreeView отображается только для исходного видимого TabItem. Может кто-нибудь указать, что я сделал не так?

Заранее спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...