1
Vote

Why must ItemsSource be type of Object? (MVVM)

description

Hi

First, I like your control very much.

But there is one big problem:
The Control replaces the items in the ItemsSource collection with it’s own classes, which means the ItemsSource-Collection must be type of Object and that other parts of the application can’t access the objects in the ItemsSource-Collection without having an reference to your FabTab library.
Unfortunately this problem makes you Control not very useful for MVVM applications.
Is there a way to change this behavior?

Code:
ItemsSourceStrategy.cs
public void AddContentsTab()
        {
            //using ItemsSource, modify collection to contain TOC Tab
            var items = _tabControl.ItemsSource as IList;
            if ( items != null )
            {
                _tabControl.ItemsSource = null;
                items.Insert( 0, _tabControl.GetContentsTab() );
                _tabControl.ItemsSource = items;
                ( _tabControl.ItemContainerGenerator.ContainerFromItem( items[ 1 ] ) as TabItem ).Focus();
            }
        }
Btw.. I’ve also discovered 2 little bugs, which cause a null reference exception when an empty TabItem gets added to the TabControl:

DragDropManager.cs
Added null check for “layer”
private static void CreatePreviewAdorner(UIElement adornedElt, IDataObject data)
        {
            if (_overlayElt != null)
                return;

            var layer = AdornerLayer.GetAdornerLayer(CurrentDropTargetAdvisor.GetTopContainer());
            if ( layer == null )
                return;
            var feedbackUI = CurrentDropTargetAdvisor.GetVisualFeedback(data);
            _overlayElt = new DropPreviewAdorner(feedbackUI, adornedElt);
            PositionAdorner();
            layer.Add(_overlayElt);
        }
ToolTipBuilder.cs
Added null check for “element”
public void SetImageScreenshotOnExTabItemAttachedProperty( FrameworkElement element, BitmapSource bitmap )
        {
            var tooltipImage = CreateImageForToolTip( bitmap );
            
            if(element == null)
                return;

            var item = element.Parent as ExTabItem;
            if ( item == null )
                item = element as ExTabItem;
            item = GetItemContainer( element, item );

            if ( item != null )
                ExTabItemProperties.SetExTabItemImage( item, tooltipImage );
            else
                throw new InvalidOperationException( "Cannot create rich tooltip because ExTabItem cannot be resolved" );
        }

comments

adajos wrote May 1, 2013 at 8:26 PM

Hi,

I'm not actively maintaining this control anymore. I've moved it to github: https://github.com/adajos/FabTab

Feel free to fork it and submit a pull request with your changes.

As far as the ItemsSource needing to be an ObservableCollection<object>, I agree it's not ideal.

But that's the only way I could find to get the ContentTabView to automatically show up, by adding it to that collection. Perhaps it would make sense to have ContentTabView implement INotifyPropertyChanged> since most other ViewModels will implement that, and then you could use ObservableCollection<INotifyPropertyChanged> for your ItemsSource. Bottom line is that as a custom UI control I have no idea what types my consumers want to stick into their ItemsSource.

Since it's open source, feel free to make ContentTabView implement some interface (IMyViewModelInterface) that you create that your other ViewModels also implement and then have your ItemsSource be ObservableCollection<IMyViewModelInterface>. Yeah, it's hacky I know. But it will work.

Good luck,

Josh