All the controls missing in WPF. Over 1 million downloads.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

317 lines
8.3 KiB

/*************************************************************************************
Extended WPF Toolkit
Copyright (C) 2007-2013 Xceed Software Inc.
This program is provided to you under the terms of the Microsoft Public
License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license
For more features, controls, and fast professional support,
pick up the Plus Edition at http://xceed.com/wpf_toolkit
Stay informed: follow @datagrid on Twitter or Like http://facebook.com/datagrids
***********************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.ObjectModel;
using System.Xml.Serialization;
namespace Xceed.Wpf.AvalonDock.Layout
{
[Serializable]
public abstract class LayoutGroup<T> : LayoutGroupBase, ILayoutContainer, ILayoutGroup, IXmlSerializable where T : class, ILayoutElement
{
#region Members
ObservableCollection<T> _children = new ObservableCollection<T>();
#endregion
#region Constructors
internal LayoutGroup()
{
_children.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler( _children_CollectionChanged );
}
#endregion
#region Properties
#region Children
public ObservableCollection<T> Children
{
get
{
return _children;
}
}
#endregion
#region IsVisible
private bool _isVisible = true;
public bool IsVisible
{
get
{
return _isVisible;
}
protected set
{
if( _isVisible != value )
{
RaisePropertyChanging( "IsVisible" );
_isVisible = value;
OnIsVisibleChanged();
RaisePropertyChanged( "IsVisible" );
}
}
}
#endregion
#region ChildrenCount
public int ChildrenCount
{
get
{
return _children.Count;
}
}
#endregion
#endregion
#region Overrides
protected override void OnParentChanged( ILayoutContainer oldValue, ILayoutContainer newValue )
{
base.OnParentChanged( oldValue, newValue );
ComputeVisibility();
}
#endregion
#region Public Methods
public void ComputeVisibility()
{
IsVisible = GetVisibility();
}
public void MoveChild( int oldIndex, int newIndex )
{
if( oldIndex == newIndex )
return;
_children.Move( oldIndex, newIndex );
ChildMoved( oldIndex, newIndex );
}
public void RemoveChildAt( int childIndex )
{
_children.RemoveAt( childIndex );
}
public int IndexOfChild( ILayoutElement element )
{
return _children.Cast<ILayoutElement>().ToList().IndexOf( element );
}
public void InsertChildAt( int index, ILayoutElement element )
{
_children.Insert( index, ( T )element );
}
public void RemoveChild( ILayoutElement element )
{
_children.Remove( ( T )element );
}
public void ReplaceChild( ILayoutElement oldElement, ILayoutElement newElement )
{
int index = _children.IndexOf( ( T )oldElement );
_children.Insert( index, ( T )newElement );
_children.RemoveAt( index + 1 );
}
public void ReplaceChildAt( int index, ILayoutElement element )
{
_children[ index ] = ( T )element;
}
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public virtual void ReadXml( System.Xml.XmlReader reader )
{
reader.MoveToContent();
if( reader.IsEmptyElement )
{
reader.Read();
ComputeVisibility();
return;
}
string localName = reader.LocalName;
reader.Read();
while( true )
{
if( ( reader.LocalName == localName ) &&
( reader.NodeType == System.Xml.XmlNodeType.EndElement ) )
{
break;
}
if( reader.NodeType == System.Xml.XmlNodeType.Whitespace )
{
reader.Read();
continue;
}
XmlSerializer serializer = null;
if( reader.LocalName == "LayoutAnchorablePaneGroup" )
serializer = new XmlSerializer( typeof( LayoutAnchorablePaneGroup ) );
else if( reader.LocalName == "LayoutAnchorablePane" )
serializer = new XmlSerializer( typeof( LayoutAnchorablePane ) );
else if( reader.LocalName == "LayoutAnchorable" )
serializer = new XmlSerializer( typeof( LayoutAnchorable ) );
else if( reader.LocalName == "LayoutDocumentPaneGroup" )
serializer = new XmlSerializer( typeof( LayoutDocumentPaneGroup ) );
else if( reader.LocalName == "LayoutDocumentPane" )
serializer = new XmlSerializer( typeof( LayoutDocumentPane ) );
else if( reader.LocalName == "LayoutDocument" )
serializer = new XmlSerializer( typeof( LayoutDocument ) );
else if( reader.LocalName == "LayoutAnchorGroup" )
serializer = new XmlSerializer( typeof( LayoutAnchorGroup ) );
else if( reader.LocalName == "LayoutPanel" )
serializer = new XmlSerializer( typeof( LayoutPanel ) );
else
{
Type type = this.FindType( reader.LocalName );
if( type == null )
throw new ArgumentException( "AvalonDock.LayoutGroup doesn't know how to deserialize " + reader.LocalName );
serializer = new XmlSerializer( type );
}
Children.Add( ( T )serializer.Deserialize( reader ) );
}
reader.ReadEndElement();
}
public virtual void WriteXml( System.Xml.XmlWriter writer )
{
foreach( var child in Children )
{
var type = child.GetType();
XmlSerializer serializer = new XmlSerializer( type );
serializer.Serialize( writer, child );
}
}
#endregion
#region Internal Methods
protected virtual void OnIsVisibleChanged()
{
UpdateParentVisibility();
}
protected abstract bool GetVisibility();
protected virtual void ChildMoved( int oldIndex, int newIndex )
{
}
#endregion
#region Private Methods
private void _children_CollectionChanged( object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e )
{
if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove ||
e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace )
{
if( e.OldItems != null )
{
foreach( LayoutElement element in e.OldItems )
{
if( element.Parent == this )
element.Parent = null;
}
}
}
if( e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add ||
e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace )
{
if( e.NewItems != null )
{
foreach( LayoutElement element in e.NewItems )
{
if( element.Parent != this )
{
if( element.Parent != null )
element.Parent.RemoveChild( element );
element.Parent = this;
}
}
}
}
ComputeVisibility();
OnChildrenCollectionChanged();
NotifyChildrenTreeChanged( ChildrenTreeChange.DirectChildrenChanged );
RaisePropertyChanged( "ChildrenCount" );
}
private void UpdateParentVisibility()
{
var parentPane = Parent as ILayoutElementWithVisibility;
if( parentPane != null )
parentPane.ComputeVisibility();
}
private Type FindType( string name )
{
foreach( var a in AppDomain.CurrentDomain.GetAssemblies() )
{
foreach( var t in a.GetTypes() )
{
if( t.Name.Equals( name ) )
return t;
}
}
return null;
}
#endregion
#region ILayoutContainer Interface
IEnumerable<ILayoutElement> ILayoutContainer.Children
{
get
{
return _children.Cast<ILayoutElement>();
}
}
#endregion
}
}