简体   繁体   中英

Extending an existing control for MVVM

I am tring to extend an existing microsoft control called the PivotViewer.

This control has an existing property that I want to expose to my ViewModel.

public ICollection<string> InScopeItemIds { get; }

I have created an inherited class called CustomPivotViewer and I want to create a Dependency Property that I can bind to that will expose the values held in InScopeItemIds in the base class.

I have spent a fair while reading up about DependencyPropertys and am becomming quite disheartened.

Is this even possible?

EDIT :

I realized misunderstandings and here is a new version (in the context of the original question):

So, you can use the property you need for the binding, with following circumstances having in mind:

  • as this property is read-only, you will not be able to use it for 2-way binding.
  • as far as the containing type does not implement INotifyPropertyChanged, your target control used to display the data will not be notified about the changes to the property value.
  • as far as the returned by this property value does not implement INotifyCollectionChanged (one example is ObservableCollection<T>), the changes to the collection will not be affected on the target control which is used to display it.

You only need a DependencyProperty is you want it to be bindable, meaning: if you want to have, for example, a MyBindableProperty property in your control, with which you want to be able to do:

MyBindableProperty={Binding SomeProperty}

if, however, you want other DependencyProperties to bind to it , any property (either a DependencyProperty or a normal one) can be used.

I'm not sure what you really need, maybe you can clarify more, but if it's the first scenario that you want to implement, you can do it as follows:

  • create a DependencyProperty , let's call it BindableInScopeItemIds , like so:

     /// <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) { } 
  • in the OnBindableInScopeItemIdsChanged , you can update the inner collection ( InScopeItemIds )

remember that the property you want to expose is read-only (it has no "setter"), so you might need to update it as so:

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

Hope this helps :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM