Hosting my user control in the FabTabItems

Jan 29, 2010 at 8:00 AM
Edited Jan 29, 2010 at 9:19 AM

Great control. But I have some propblems. My application has list of the elements at the left side and the tab control at the right. And while I use standard WPF TabControl I can drag elements from the list and drop them into my user control. But when I change standard control by FabTabControl I can't drop elements...

Coordinator
Jan 29, 2010 at 2:24 PM
Edited Jan 29, 2010 at 10:41 PM

Hey sevalt,

If you can put together a standalone sample that replicates this issue in a sample solution and send it to me I'll happily take a closer look at it.  Since it sounds like you are dragging and dropping things from outside of the FabTabControl into a user control that you have created which lives inside a FabTabItem, then I'm guessing that FabTab's drag and drop support for re-ordering tabs might be clashing with yours.  I would try two things:

1.  Try setting AllowDragAndDropTabReordering="False" on the FabTabControl and see if that removes the problem

2.  If you try #1 and that doesn't work, then in generic.xaml comment out the following two Setters on the Style for FabTabItem:

<Setter Property="dd:DragDropManager.DragSourceAdvisor" Value="{StaticResource advisor}"/>

<Setter Property="dd:DragDropManager.DropTargetAdvisor" Value="{StaticResource advisor}"/>

Let me know if you're still having problems with it after that, if so, probably the best way for me to get to the bottom of it is for you to create a simple sample solution that demonstrates the issue so I can see if for myself. Hope these options help--if either of these options removes your problem, please let us all know by posting back to this discussion thread.  I'm sure you won't be the only person to run into this sort of issue.

Thanks!

Josh

Jan 30, 2010 at 7:43 AM
Edited Jan 30, 2010 at 9:07 AM

Hello, adajos! First your advise really helped. But what I need to do for allow both AllowDragAndDropTabReordering and Drag and Drop objects from outside the tab control inside it? And the next question: I override your TabItem as following

/// <summary>
    /// Class represents the closeable tab item with TPDEDiagram object inside
    /// </summary>
    public class TPDETabItem: FabTabItem
    {
        #region Data
        /// <summary>
        /// Diagram object inside the tab item
        /// </summary>
        private TPDEDiagram m_Diagram = null;
        /// <summary>
        /// Indicates state of showing anchor points of the node inside tab item
        /// </summary>
        private ShowAnchors? m_nShowAnchors = null;
        /// <summary>
        /// State of show anchors button. True == checked, false == unchekked
        /// </summary>
        private bool m_bShowAnchorsBtnState = false;
        #endregion //Data

        #region Constructors
        public TPDETabItem():   base()
        {
        }
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="a_Diagram">Diagram inside the tab item</param>
        /// <param name="a_sHeader">Header of tab item</param>
        public TPDETabItem(TPDEDiagram a_Diagram, String a_sHeader): base()
        {
            m_Diagram = a_Diagram;
            Header = a_sHeader;
            Content = m_Diagram;
        }
        /// <summary>
        /// Static constructor
        /// </summary>
        static TPDETabItem()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TPDETabItem),
                new FrameworkPropertyMetadata(typeof(TPDETabItem)));
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets diagram object
        /// </summary>
        public Diagram Diagram
        {
            get { return m_Diagram.m_Diagram; }
        }
        /// <value>
        /// Gets or sets style of showing anchor points of the nodes
        /// </value>
        public ShowAnchors? ShowAnchors
        {
            get { return m_nShowAnchors; }
            set { m_nShowAnchors = value; }
        }
        /// <value>
        /// Gets or set state of show anchors button.
        /// For details see <seealso cref="m_bShowAnchorsBtnState"/>
        /// </value>
        public bool ShowAnchorsBtnState
        {
            get { return m_bShowAnchorsBtnState; }
            set { m_bShowAnchorsBtnState = value; }
        }
        #endregion //Properties

But when I create items I cant see the header.

 

Jan 30, 2010 at 9:34 AM
Edited Jan 30, 2010 at 9:41 AM

And also my application crashes when I try to close tabitem from the Content tab. I can't understand why but I catches TabClosing event 3 times in this case. And after that I go to the void newClosableTabItem_TabClosing(object sender, RoutedEventArgs e) of FabTabControl and catches an exception after

//when a tab closes that happens be the source or target on either of the advisors
                                //it will disallow further drag and drop operations.  therefore whenever a tab closes
                                //reset this to something valid, in this case, the last item in the collection.
                                DragDropManager.GetDragSourceAdvisor(lastTabItem).SourceUI = lastTabItem;
                                DragDropManager.GetDropTargetAdvisor(lastTabItem).TargetUI = lastTabItem;

I modified this code as

this.CloseTab(closingTab);
                    if (this.SelectedItem != null)
                    {
                        FabTabItem lastTabItem = this.ItemContainerGenerator.ContainerFromIndex(this.Items.Count - 1) as FabTabItem;
                        if (lastTabItem != null)
                        {
                            try
                            {
                                //when a tab closes that happens be the source or target on either of the advisors
                                //it will disallow further drag and drop operations.  therefore whenever a tab closes
                                //reset this to something valid, in this case, the last item in the collection.
                                DragDropManager.GetDragSourceAdvisor(lastTabItem).SourceUI = lastTabItem;
                                DragDropManager.GetDropTargetAdvisor(lastTabItem).TargetUI = lastTabItem;
                            }
                            catch (System.Exception ex)
                            {
                                MessageBox.Show(ex.Message);
                            }                                                                                                               
                        }
                        
                    }

And I see an exception message such as "Object reference not set to an instance of an object." But lastTabItem variable isn't null and holds my user control. And this user control is valid. Also for some reason lastTabItem.closeTabItemButton is null.

Coordinator
Jan 30, 2010 at 4:30 PM

sevalt,

I don't really have enough information to answer your question.  So you've subclassed FabTabItem, have you then also modified FabTabControl to return instances of your subclass rather than FabTabItem as it is coded to do.  Remember, FabTabControl is authored specifically to use FabTabItem, so since it's open source it might just be easier for you to add any changes you need to FabTabItem right into that class rather than subclassing it and then having to drastically modify FabTabControl as well as the dragdropadvisor.

Also, have you pointed your subclassed FabTabItem to the exact same ControlTemplate as FabTabItem?  Are you then declaring your subclassed FabTabItems directly in XAML, or are you just putting your user controls in the xaml in the FabTabControl's Items collection and letting the control generate the tab item container?

It's really going to be much easier if you can send me a sample solution that has the same problems as you are seeing, it's pretty tricky to guess what the problem is otherwise. But minimally I'd need to see your XAML where you're declaring FabTabControl and also the XAML you are using for your ControlTemplates for your subclassed FabTabItem.

Josh

Jan 30, 2010 at 5:11 PM
Edited Jan 30, 2010 at 5:14 PM

Hello, adajos! I can send you the solution example only at Monday. But I try to modify FabTabItem class according to your recomendations. I generate my tab items directly from code. I don't use for this purpose XAML at all. Please, send me your e-mail or post it in this discussion and I send you my solution as zip-archive.

Feb 1, 2010 at 6:17 AM

Hello, adajos! I change my derived tab item by FabTabItem and all work ok. But about drag and drop. It started work only when I comment setters. Before it worked with my derived class. And when I try to close tab item from the content view I handle th TabClosing several times and after that I catches an exception.

Feb 1, 2010 at 7:23 AM

How can I change the style of the TabControl and TabItems. For all standard controls I use the following code:

<Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/PresentationFramework.Classic, Version=3.0.0.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35;component/themes/Classic.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>

public enum Skin
        {
            Classic = 0,
            Aero,
            Luna,
            LunaMetallic,
            LunaHomeStead,
            Royal,
        };

private void ChangeSkin(Skin a_nNewSkin)
        {
            string[] uris = {
                "/PresentationFramework.Classic, Version=3.0.0.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35;component/themes/Classic.xaml",
                "/PresentationFramework.Aero, Version=3.0.0.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35;component/themes/aero.normalcolor.xaml",
                "/PresentationFramework.Luna,Version=3.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35;component/themes/luna.normalcolor.xaml",
                "/PresentationFramework.Luna,Version=3.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35;component/themes/luna.metallic.xaml",
                "/PresentationFramework.Luna,Version=3.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35;component/themes/luna.homestead.xaml",
                "/PresentationFramework.Royale,Version=3.0.0.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35;component/themes/royale.normalcolor.xaml",
            };
            Uri uriToTheme = new Uri(uris[(int)a_nNewSkin], UriKind.Relative);
            object theme = Application.LoadComponent(uriToTheme);
            if (App.Current.Resources.MergedDictionaries.Count > 0)
                App.Current.Resources.MergedDictionaries[0] = (ResourceDictionary)theme;
        }

 

Is there any way to make changes of style similiar?