这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ namespace AvalonDock.Controls
/// Provides a control to display multible (or just one) LayoutAnchorable(s).
/// See also <seealso cref="AnchorablePaneTabPanel"/>.
/// </summary>
/// <seealso cref="TabControl"/>
/// <seealso cref="TabControlEx"/>
/// <seealso cref="ILayoutControl"/>
public class LayoutAnchorablePaneControl : TabControl, ILayoutControl//, ILogicalChildrenContainer
public class LayoutAnchorablePaneControl : TabControlEx, ILayoutControl//, ILogicalChildrenContainer
{
#region fields
private LayoutAnchorablePane _model;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ namespace AvalonDock.Controls
/// TabItem Header (<see cref="LayoutDocumentTabItem"/>) that contains the document titles
/// inside the <see cref="DocumentPaneTabPanel"/>.
/// </summary>
/// <seealso cref="TabControl"/>
/// <seealso cref="TabControlEx"/>
/// <seealso cref="ILayoutControl"/>
public class LayoutDocumentPaneControl : TabControl, ILayoutControl//, ILogicalChildrenContainer
public class LayoutDocumentPaneControl : TabControlEx, ILayoutControl//, ILogicalChildrenContainer
{
#region fields
private LayoutDocumentPane _model;
Expand Down
201 changes: 201 additions & 0 deletions source/Components/AvalonDock/TabControlEx.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
using System;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;

namespace AvalonDock
{
/// <summary>
/// This control added to mitigate issue with tab (document) switching speed
/// See this https://stackoverflow.com/questions/2080764/how-to-preserve-control-state-within-tab-items-in-a-tabcontrol
/// and this https://stackoverflow.com/questions/31030293/cefsharp-in-tabcontrol-not-working/37171847#37171847
/// </summary>
[TemplatePart(Name = "PART_ItemsHolder", Type = typeof(Panel))]
public class TabControlEx : TabControl
{
private Panel ItemsHolderPanel = null;

public TabControlEx()
: base()
{
// This is necessary so that we get the initial databound selected item
ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;
}

/// <summary>
/// If containers are done, generate the selected item
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
if (this.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
this.ItemContainerGenerator.StatusChanged -= ItemContainerGenerator_StatusChanged;
UpdateSelectedItem();
}
}

/// <summary>
/// Get the ItemsHolder and generate any children
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
ItemsHolderPanel = CreateGrid();
// exchange ContentPresenter for Grid
var topGrid = (Grid)GetVisualChild(0);

if (topGrid != null)
{
if (topGrid.Children != null && topGrid.Children.Count > 2)
{
if (topGrid.Children[1] is Border)
{
var border = (Border)topGrid.Children[1];
border.Child = ItemsHolderPanel;
}
else if (topGrid.Children[2] is Border)
{
var border = (Border)topGrid.Children[2];
border.Child = ItemsHolderPanel;
}
}
}

UpdateSelectedItem();
}

private Grid CreateGrid()
{
var grid = new Grid();
Binding binding = new Binding(PaddingProperty.Name);
binding.Source = this; // view model?
grid.SetBinding(Grid.MarginProperty, binding);

binding = new Binding(SnapsToDevicePixelsProperty.Name);
binding.Source = this; // view model?
grid.SetBinding(Grid.SnapsToDevicePixelsProperty, binding);

return grid;
}

/// <summary>
/// When the items change we remove any generated panel children and add any new ones as necessary
/// </summary>
/// <param name="e"></param>
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);

if (ItemsHolderPanel == null)
return;

switch (e.Action)
{
case NotifyCollectionChangedAction.Reset:
ItemsHolderPanel.Children.Clear();
break;

case NotifyCollectionChangedAction.Add:
case NotifyCollectionChangedAction.Remove:
if (e.OldItems != null)
{
foreach (var item in e.OldItems)
{
ContentPresenter cp = FindChildContentPresenter(item);
if (cp != null)
ItemsHolderPanel.Children.Remove(cp);
}
}

// Don't do anything with new items because we don't want to
// create visuals that aren't being shown

UpdateSelectedItem();
break;

case NotifyCollectionChangedAction.Replace:
throw new NotImplementedException("Replace not implemented yet");
}
}

protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
UpdateSelectedItem();
}

private void UpdateSelectedItem()
{
if (ItemsHolderPanel == null)
return;

// Generate a ContentPresenter if necessary
TabItem item = GetSelectedTabItem();
if (item != null)
CreateChildContentPresenter(item);

// show the right child
foreach (ContentPresenter child in ItemsHolderPanel.Children)
child.Visibility = ((child.Tag as TabItem).IsSelected) ? Visibility.Visible : Visibility.Collapsed;
}

private ContentPresenter CreateChildContentPresenter(object item)
{
if (item == null)
return null;

ContentPresenter cp = FindChildContentPresenter(item);

if (cp != null)
return cp;

// the actual child to be added. cp.Tag is a reference to the TabItem
cp = new ContentPresenter();
cp.Content = (item is TabItem) ? (item as TabItem).Content : item;
cp.ContentTemplate = this.SelectedContentTemplate;
cp.ContentTemplateSelector = this.SelectedContentTemplateSelector;
cp.ContentStringFormat = this.SelectedContentStringFormat;
cp.Visibility = Visibility.Collapsed;
cp.Tag = (item is TabItem) ? item : (this.ItemContainerGenerator.ContainerFromItem(item));
ItemsHolderPanel.Children.Add(cp);
return cp;
}

private ContentPresenter FindChildContentPresenter(object data)
{
if (data is TabItem)
data = (data as TabItem).Content;

if (data == null)
return null;

if (ItemsHolderPanel == null)
return null;

foreach (ContentPresenter cp in ItemsHolderPanel.Children)
{
if (cp.Content == data)
return cp;
}

return null;
}

protected TabItem GetSelectedTabItem()
{
object selectedItem = base.SelectedItem;
if (selectedItem == null)
return null;

TabItem item = selectedItem as TabItem;
if (item == null)
item = base.ItemContainerGenerator.ContainerFromIndex(base.SelectedIndex) as TabItem;

return item;
}
}
}