what is the difference between the two?
WPF's DockPanel:
RadDockPanel:
in which cases should i use RadDockPanel?
WPF's DockPanel:
/// <summary>
/// DockPanel is used to size and position children inward from the edges of available space.
///
/// A <see cref="System.Windows.Controls.Dock" /> enum (see <see cref="SetDock" /> and <see cref="GetDock" />)
/// determines on which size a child is placed. Children are stacked in order from these edges until
/// there is no more space; this happens when previous children have consumed all available space, or a child
/// with Dock set to Fill is encountered.
/// </summary>
public
class
DockPanel : Panel
{
//-------------------------------------------------------------------
//
// Constructors
//
//-------------------------------------------------------------------
#region Constructors
/// <summary>
/// Default DependencyObject constructor
/// </summary>
/// <remarks>
/// Automatic determination of current Dispatcher. Use alternative constructor
/// that accepts a Dispatcher for best performance.
/// </remarks>
public
DockPanel() :
base
()
{
}
#endregion
//--------------------------------------------------------------------
//
// Public Methods
//
//-------------------------------------------------------------------
#region Public Methods
/// <summary>
/// Reads the attached property Dock from the given element.
/// </summary>
/// <param name="element">UIElement from which to read the attached property.</param>
/// <returns>The property's value.</returns>
/// <seealso cref="DockPanel.DockProperty" />
[AttachedPropertyBrowsableForChildren()]
public
static
Dock GetDock(UIElement element)
{
if
(element ==
null
) {
throw
new
ArgumentNullException(
"element"
); }
return
(Dock) element.GetValue(DockProperty);
}
/// <summary>
/// Writes the attached property Dock to the given element.
/// </summary>
/// <param name="element">UIElement to which to write the attached property.</param>
/// <param name="dock">The property value to set</param>
/// <seealso cref="DockPanel.DockProperty" />
public
static
void
SetDock(UIElement element, Dock dock)
{
if
(element ==
null
) {
throw
new
ArgumentNullException(
"element"
); }
element.SetValue(DockProperty, dock);
}
private
static
void
OnDockChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
UIElement uie = d
as
UIElement;
//it may be anyting, like FlowDocument... bug 1237275
if
(uie !=
null
)
{
DockPanel p = VisualTreeHelper.GetParent(uie)
as
DockPanel;
if
(p !=
null
)
{
p.InvalidateMeasure();
}
}
}
#endregion
//--------------------------------------------------------------------
//
// Public Properties + Dependency Properties's
//
//--------------------------------------------------------------------
#region Public Properties
/// <summary>
/// This property controls whether the last child in the DockPanel should be stretched to fill any
/// remaining available space.
/// </summary>
public
bool
LastChildFill
{
get
{
return
(
bool
) GetValue(LastChildFillProperty); }
set
{ SetValue(LastChildFillProperty, value); }
}
/// <summary>
/// DependencyProperty for <see cref="LastChildFill" /> property.
/// </summary>
[CommonDependencyProperty]
public
static
readonly
DependencyProperty LastChildFillProperty =
DependencyProperty.Register(
"LastChildFill"
,
typeof
(
bool
),
typeof
(DockPanel),
new
FrameworkPropertyMetadata(
true
, FrameworkPropertyMetadataOptions.AffectsArrange));
/// <summary>
/// DependencyProperty for Dock property.
/// </summary>
/// <seealso cref="DockPanel.GetDock" />
/// <seealso cref="DockPanel.SetDock" />
[CommonDependencyProperty]
public
static
readonly
DependencyProperty DockProperty =
DependencyProperty.RegisterAttached(
"Dock"
,
typeof
(Dock),
typeof
(DockPanel),
new
FrameworkPropertyMetadata(
Dock.Left,
new
PropertyChangedCallback(OnDockChanged)),
new
ValidateValueCallback(IsValidDock));
#endregion
//-------------------------------------------------------------------
//
// Protected Methods
//
//--------------------------------------------------------------------
#region Protected Methods
/// <summary>
/// Updates DesiredSize of the DockPanel. Called by parent UIElement. This is the first pass of layout.
/// </summary>
/// <remarks>
/// Children are measured based on their sizing properties and <see cref="System.Windows.Controls.Dock" />.
/// Each child is allowed to consume all of the space on the side on which it is docked; Left/Right docked
/// children are granted all vertical space for their entire width, and Top/Bottom docked children are
/// granted all horizontal space for their entire height.
/// </remarks>
/// <param name="constraint">Constraint size is an "upper limit" that the return value should not exceed.</param>
/// <returns>The Panel's desired size.</returns>
protected
override
Size MeasureOverride(Size constraint)
{
UIElementCollection children = InternalChildren;
double
parentWidth = 0;
// Our current required width due to children thus far.
double
parentHeight = 0;
// Our current required height due to children thus far.
double
accumulatedWidth = 0;
// Total width consumed by children.
double
accumulatedHeight = 0;
// Total height consumed by children.
for
(
int
i = 0, count = children.Count; i < count; ++i)
{
UIElement child = children[i];
Size childConstraint;
// Contains the suggested input constraint for this child.
Size childDesiredSize;
// Contains the return size from child measure.
if
(child ==
null
) {
continue
; }
// Child constraint is the remaining size; this is total size minus size consumed by previous children.
childConstraint =
new
Size(Math.Max(0.0, constraint.Width - accumulatedWidth),
Math.Max(0.0, constraint.Height - accumulatedHeight));
// Measure child.
child.Measure(childConstraint);
childDesiredSize = child.DesiredSize;
// Now, we adjust:
// 1. Size consumed by children (accumulatedSize). This will be used when computing subsequent
// children to determine how much space is remaining for them.
// 2. Parent size implied by this child (parentSize) when added to the current children (accumulatedSize).
// This is different from the size above in one respect: A Dock.Left child implies a height, but does
// not actually consume any height for subsequent children.
// If we accumulate size in a given dimension, the next child (or the end conditions after the child loop)
// will deal with computing our minimum size (parentSize) due to that accumulation.
// Therefore, we only need to compute our minimum size (parentSize) in dimensions that this child does
// not accumulate: Width for Top/Bottom, Height for Left/Right.
switch
(DockPanel.GetDock(child))
{
case
Dock.Left:
case
Dock.Right:
parentHeight = Math.Max(parentHeight, accumulatedHeight + childDesiredSize.Height);
accumulatedWidth += childDesiredSize.Width;
break
;
case
Dock.Top:
case
Dock.Bottom:
parentWidth = Math.Max(parentWidth, accumulatedWidth + childDesiredSize.Width);
accumulatedHeight += childDesiredSize.Height;
break
;
}
}
// Make sure the final accumulated size is reflected in parentSize.
parentWidth = Math.Max(parentWidth, accumulatedWidth);
parentHeight = Math.Max(parentHeight, accumulatedHeight);
return
(
new
Size(parentWidth, parentHeight));
}
/// <summary>
/// DockPanel computes a position and final size for each of its children based upon their
/// <see cref="System.Windows.Controls.Dock" /> enum and sizing properties.
/// </summary>
/// <param name="arrangeSize">Size that DockPanel will assume to position children.</param>
protected
override
Size ArrangeOverride(Size arrangeSize)
{
UIElementCollection children = InternalChildren;
int
totalChildrenCount = children.Count;
int
nonFillChildrenCount = totalChildrenCount - (LastChildFill ? 1 : 0);
double
accumulatedLeft = 0;
double
accumulatedTop = 0;
double
accumulatedRight = 0;
double
accumulatedBottom = 0;
for
(
int
i = 0; i < totalChildrenCount; ++i)
{
UIElement child = children[i];
if
(child ==
null
) {
continue
; }
Size childDesiredSize = child.DesiredSize;
Rect rcChild =
new
Rect(
accumulatedLeft,
accumulatedTop,
Math.Max(0.0, arrangeSize.Width - (accumulatedLeft + accumulatedRight)),
Math.Max(0.0, arrangeSize.Height - (accumulatedTop + accumulatedBottom)) );
if
(i < nonFillChildrenCount)
{
switch
(DockPanel.GetDock(child))
{
case
Dock.Left:
accumulatedLeft += childDesiredSize.Width;
rcChild.Width = childDesiredSize.Width;
break
;
case
Dock.Right:
accumulatedRight += childDesiredSize.Width;
rcChild.X = Math.Max(0.0, arrangeSize.Width - accumulatedRight);
rcChild.Width = childDesiredSize.Width;
break
;
case
Dock.Top:
accumulatedTop += childDesiredSize.Height;
rcChild.Height = childDesiredSize.Height;
break
;
case
Dock.Bottom:
accumulatedBottom += childDesiredSize.Height;
rcChild.Y = Math.Max(0.0, arrangeSize.Height - accumulatedBottom);
rcChild.Height = childDesiredSize.Height;
break
;
}
}
child.Arrange(rcChild);
}
return
(arrangeSize);
}
#endregion Protected Methods
//-------------------------------------------------------------------
//
// Private Methods
//
//-------------------------------------------------------------------
#region Private Methods
internal
static
bool
IsValidDock(
object
o)
{
Dock dock = (Dock)o;
return
( dock == Dock.Left
|| dock == Dock.Top
|| dock == Dock.Right
|| dock == Dock.Bottom);
}
//
// This property
// 1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject
// 2. This is a performance optimization
//
internal
override
int
EffectiveValuesInitialSize
{
get
{
return
9; }
}
#endregion Private Methods
}
RadDockPanel:
/// <summary>
/// Defines an area where you can arrange child elements either horizontally or vertically, relative to each other.
/// </summary>
[DefaultProperty(
"LastChildFill"
)]
public
class
RadDockPanel : Panel
{
/// <summary>
/// Identifies the Dock attached property.
/// </summary>
public
static
readonly
DependencyProperty DockProperty =
DependencyProperty.RegisterAttached(
"Dock"
,
typeof
(Dock),
typeof
(RadDockPanel),
new
System.Windows.PropertyMetadata(Dock.Left, RadDockPanel.OnDockChanged));
/// <summary>
/// Identifies the LastChildFill dependency property.
/// </summary>
public
static
readonly
DependencyProperty LastChildFillProperty =
DependencyProperty.Register(
"LastChildFill"
,
typeof
(
bool
),
typeof
(RadDockPanel),
new
System.Windows.PropertyMetadata(
true
, RadDockPanel.OnLastChildFillChanged));
/// <summary>
/// Initializes a new instance of the <see cref="RadDockPanel"/> class.
/// </summary>
public
RadDockPanel()
{
TelerikLicense.Verify(
this
);
}
/// <summary>
/// Gets or sets a value that indicates whether the last child element within
/// a DockPanel stretches to fill the remaining available space. This is a dependency property.
/// </summary>
public
bool
LastChildFill
{
get
{
return
(
bool
)GetValue(LastChildFillProperty);
}
set
{
SetValue(LastChildFillProperty, value);
}
}
/// <summary>
/// Gets the value of the Dock attached property for a specified UIElement.
/// </summary>
/// <param name="element">The element from which the property value is read.</param>
/// <returns>The Dock property value for the element.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"Microsoft.Design"
,
"CA1011:ConsiderPassingBaseTypesAsParameters"
, Justification =
"Dock should be used on UIElements only."
)]
public
static
Dock GetDock(UIElement element)
{
if
(element ==
null
)
{
throw
new
ArgumentNullException(
"element"
);
}
return
(Dock)element.GetValue(DockProperty);
}
/// <summary>
/// Sets the value of the Dock attached property to a specified element.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"Microsoft.Design"
,
"CA1011:ConsiderPassingBaseTypesAsParameters"
, Justification =
"Dock should be used on UIElements only."
)]
public
static
void
SetDock(UIElement element, Dock dock)
{
if
(element ==
null
)
{
throw
new
ArgumentNullException(
"element"
);
}
element.SetValue(DockProperty, dock);
}
internal
static
bool
IsValidDock(
object
o)
{
Dock dock = (Dock)o;
if
(((dock != Dock.Left) && (dock != Dock.Top)) && (dock != Dock.Right))
{
return
dock == Dock.Bottom;
}
return
true
;
}
/// <summary>
/// Provides the behavior for the "Arrange" pass of Silverlight layout. Classes can override this method to define their own arrange pass behavior.
/// </summary>
/// <param name="finalSize">The final area within the parent that this element should use to arrange itself and its children.</param>
/// <returns>The actual size used.</returns>
protected
override
Size ArrangeOverride(Size finalSize)
{
UIElementCollection internalChildren = Children;
int
count = internalChildren.Count;
int
num2 = count - (
this
.LastChildFill ? 1 : 0);
double
x = 0.0;
double
y = 0.0;
double
num5 = 0.0;
double
num6 = 0.0;
for
(
int
i = 0; i < count; i++)
{
UIElement element = internalChildren[i];
if
(element !=
null
)
{
Size desiredSize = element.DesiredSize;
Rect finalRect =
new
Rect(x, y, Math.Max((
double
)0.0, (
double
)(finalSize.Width - (x + num5))), Math.Max((
double
)0.0, (
double
)(finalSize.Height - (y + num6))));
if
(i < num2)
{
switch
(GetDock(element))
{
case
Dock.Left:
x += desiredSize.Width;
finalRect.Width = desiredSize.Width;
break
;
case
Dock.Top:
y += desiredSize.Height;
finalRect.Height = desiredSize.Height;
break
;
case
Dock.Right:
num5 += desiredSize.Width;
finalRect.X = Math.Max((
double
)0.0, (
double
)(finalSize.Width - num5));
finalRect.Width = desiredSize.Width;
break
;
case
Dock.Bottom:
num6 += desiredSize.Height;
finalRect.Y = Math.Max((
double
)0.0, (
double
)(finalSize.Height - num6));
finalRect.Height = desiredSize.Height;
break
;
}
}
element.Arrange(finalRect);
}
}
return
finalSize;
}
/// <summary>
/// Provides the behavior for the "measure" pass of Silverlight layout. Classes can override this method to define their own measure pass behavior.
/// </summary>
/// <param name="availableSize">The available size that this element can give to child elements. Infinity can be specified as a value to indicate that the element will size to whatever content is available.</param>
/// <returns>
/// The size that this element determines it needs during layout, based on its calculations of child element sizes.
/// </returns>
protected
override
Size MeasureOverride(Size availableSize)
{
UIElementCollection internalChildren = Children;
double
num = 0.0;
double
num2 = 0.0;
double
num3 = 0.0;
double
num4 = 0.0;
int
num5 = 0;
int
count = internalChildren.Count;
while
(num5 < count)
{
UIElement element = internalChildren[num5];
if
(element !=
null
)
{
Size remainingSize =
new
Size(Math.Max((
double
)0.0, (
double
)(availableSize.Width - num3)), Math.Max((
double
)0.0, (
double
)(availableSize.Height - num4)));
element.Measure(remainingSize);
Size desiredSize = element.DesiredSize;
switch
(GetDock(element))
{
case
Dock.Left:
case
Dock.Right:
num2 = Math.Max(num2, num4 + desiredSize.Height);
num3 += desiredSize.Width;
break
;
case
Dock.Top:
case
Dock.Bottom:
num = Math.Max(num, num3 + desiredSize.Width);
num4 += desiredSize.Height;
break
;
}
}
num5++;
}
num = Math.Max(num, num3);
return
new
Size(num, Math.Max(num2, num4));
}
private
static
void
OnDockChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if
(!RadDockPanel.IsValidDock(e.NewValue))
{
throw
new
ArgumentException(
"Invalid Dock value"
);
}
FrameworkElement reference = d
as
FrameworkElement;
if
(reference !=
null
)
{
RadDockPanel parent = reference.Parent
as
RadDockPanel;
if
(parent !=
null
)
{
parent.InvalidateMeasure();
}
}
}
private
static
void
OnLastChildFillChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
RadDockPanel panel = d
as
RadDockPanel;
if
(panel !=
null
)
{
panel.InvalidateArrange();
}
}
}
in which cases should i use RadDockPanel?