Расширение существующего элемента управления для MVVM - PullRequest
2 голосов
/ 05 апреля 2011

Я пытаюсь расширить существующий элемент управления Microsoft под названием PivotViewer.

У этого элемента управления есть существующее свойство, которое я хочу предоставить моей ViewModel.

public ICollection<string> InScopeItemIds { get; }

Я создал унаследованный класс с именем CustomPivotViewer, и я хочу создать свойство зависимости, к которому я могу привязать, которое будет отображать значения, содержащиеся в InScopeItemIds в базовом классе.

Я потратил много времени, читая о DependencyPropertys, и очень расстраиваюсь.

Это вообще возможно?

Ответы [ 2 ]

0 голосов
/ 05 апреля 2011

Вам нужен только DependencyProperty, если вы хотите, чтобы it был привязываемым, что означает: если вы хотите иметь, например, свойство MyBindableProperty в вашем контроле, с которым вы хотите бытьспособен сделать:

MyBindableProperty={Binding SomeProperty}

, если, однако, вы хотите, чтобы other DependencyProperties связал с ним , любым свойством (либо DependencyProperty, либообычный) можно использовать.

Я не уверен, что вам действительно нужно, может быть, вы сможете уточнить больше, но если это первый сценарий, который вы хотите реализовать, вы можете сделать это следующим образом:

  • создайте DependencyProperty, назовем его BindableInScopeItemIds, вот так:

    /// <summary>
    /// BindableInScopeItemIds Dependency Property
    /// </summary>
    public static readonly DependencyProperty BindableInScopeItemIdsProperty =
        DependencyProperty.Register("BindableInScopeItemIds", typeof(ICollection<string>), typeof(CustomPivotViewer),
            new PropertyMetadata(null,
                new PropertyChangedCallback(OnBindableInScopeItemIdsChanged)));
    
    /// <summary>
    /// Gets or sets the BindableInScopeItemIds property. This dependency property 
    /// indicates ....
    /// </summary>
    public ICollection<string> BindableInScopeItemIds
    {
        get { return (ICollection<string>)GetValue(BindableInScopeItemIdsProperty); }
        set { SetValue(BindableInScopeItemIdsProperty, value); }
    }
    
    /// <summary>
    /// Handles changes to the BindableInScopeItemIds property.
    /// </summary>
    private static void OnBindableInScopeItemIdsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var target = (CustomPivotViewer)d;
        ICollection<string> oldBindableInScopeItemIds = (ICollection<string>)e.OldValue;
        ICollection<string> newBindableInScopeItemIds = target.BindableInScopeItemIds;
        target.OnBindableInScopeItemIdsChanged(oldBindableInScopeItemIds, newBindableInScopeItemIds);
    }
    
    /// <summary>
    /// Provides derived classes an opportunity to handle changes to the BindableInScopeItemIds property.
    /// </summary>
    protected virtual void OnBindableInScopeItemIdsChanged(ICollection<string> oldBindableInScopeItemIds, ICollection<string> newBindableInScopeItemIds)
    {
    }
    
  • в OnBindableInScopeItemIdsChanged, вы можете обновитьвнутренняя коллекция (InScopeItemIds)

помните, что свойство, которое вы хотите предоставить, только для чтения (у него нет «установщика»), так что вы можетенужно обновить его так:

protected virtual void OnBindableInScopeItemIdsChanged(ICollection<string> oldBindableInScopeItemIds, ICollection<string> newBindableInScopeItemIds)
{
    InScopeItemIds.Clear();
    foreach (var itemId in newBindableInScopeItemIds)
    {
        InScopeItemIds.Add(itemId);
    }
}

Надеюсь, это поможет:)

0 голосов
/ 05 апреля 2011

EDIT

Я понял недоразумения, и вот новая версия (в контексте исходного вопроса):

Таким образом, вы можете использовать свойство, необходимое для привязки, с учетом следующих обстоятельств:

  • , поскольку это свойство доступно только для чтения, вы не сможете использовать его для двусторонней привязки.
  • , поскольку содержащий тип не реализует INotifyPropertyChanged, целевой элемент управления, используемый для отображения данных, не будет уведомлен об изменениях значения свойства.
  • , поскольку возвращаемое этим значением свойства не реализует INotifyCollectionChanged (один пример - ObservableCollection ), изменения в коллекции не будут затронуты целевым элементом управления, который используется для его отображения.
...