1.はじめに
この記事では、2段階のプロセスレイアウトWPFのUI要素、およびのみ達成することができるものコンテンツリサイズコントロールを測定用いて導入することを記載しています。
私は初心者にアニメーションを行うにはあまりにも多くの仕事をお勧めしませんが、アニメーションは、ユーザーエクスペリエンスを向上させ、視界の適切な行にユーザーを誘導することができます。例えば、コンテンツの高さを変更する場合、このアニメーションの図は、アニメーションは非常に一般的です、動的に高さを変更、格好良いに加えて、ユーザーエクスペリエンスを向上させることも有用です。残念ながら、WPF自体も、エキスパンダー拡大/縮小、この点では、デフォルトではこの機能をサポートしていませんが何のアニメーションではありません。このような理由から、私はコンテンツのサイズを変更する場合(そのサイズのリサイズ制御を変更するには、アニメーションの方法を達成することができリクエスト推奨、どのような良い名前を考えると)。実際には、Silverlightのから正直にツールキットの移植AccordionItemのような、しかし私は、このコントロールのレイアウト(およびアニメーション)によって導入された概念のいくつかを考えます。次のようにリサイズを示すXAMLを使用しました:
lt;StackPanelgt;
lt;kino:KinoResizer HorizontalContentAlignment=quot;Stretchquot;gt;
lt;Expander Header=quot;Expander1quot;gt;
lt;Rectangle Height=quot;100quot;
Fill=quot;Redquot; /gt;
lt;/Expandergt;
lt;/kino:KinoResizergt;
lt;kino:KinoResizer HorizontalContentAlignment=quot;Stretchquot;gt;
lt;Expander Header=quot;Expander2quot;gt;
lt;Rectangle Height=quot;100quot;
Fill=quot;Bluequot; /gt;
lt;/Expandergt;
lt;/kino:KinoResizergt;
lt;/StackPanelgt;
2.必要の概念を理解します
これを実現するために、我々は最初のプロセス制御レイアウトWPFのUI要素を理解する必要があります。
2.1二段階プロセスレイアウト
WPFレイアウトは、実質的に第1のレイアウト要素を再帰的レイアウトを実現アレンジ次いで、すべての子要素の測定と必要なサイズを計算し、測定し、2つのステップにアレンジ。
StackPanelに、例えば、時に必要のStackPanelレイアウト、それは最初に提供されていますどのくらいのスペースを知っている必要があり、その後、子供、彼らが必要とするどのくらいのスペースのすべての子を依頼する利用可能なスペースを使用しますが、これは測定され、スペースを必要とするすべての子要素独自のサブ要素のレイアウトロジックの後に配置され、インストールの実際のサイズと位置を決定します。
StackPanelレイアウトを再場合(例えば、サイズ変更のStackPanel)、二段階プロセスは、のStackPanelレイアウトを繰り返す今回。StackPanelの子要素を再配置する必要がある場合、それは再通知のStackPanelレイアウトする必要があります。
2.2 MeasureOverride
MeasureOverride派生クラスのオーバーライドで、レイアウト内のサイズを測定するために必要なサブ要素。議論するために自分自身と自分の子要素の後に再び使用可能にどのくらいのスペース親要素は、単に私たちは親要素の大きさを伝える必要があり、自分自身を教えています。
2.3 DesiredSizeを
DesiredSizeをの測定を見た後決定されたサイズを指します。次のコードは、MeasureOverrideとDesiredSizeをを使用する方法を示します。
protected override Size MeasureOverride(Size availableSize)
{
Size panelDesiredSize = new Size();
// In our example, we just have one child.
// Report that our panel requires just the size of its only child.
foreach (UIElement child in InternalChildren)
{
child.Measure(availableSize);
panelDesiredSize = child.DesiredSize;
}
return panelDesiredSize ;
}
2.4 InvalidateMeasure
InvalidateMeasure現在の対策の無効なレイアウト要素、および非同期に再測定をトリガ。
2.5 IsMeasureValid
IsMeasureValid有効なリターンを測定する現在のサイズ分布を示すので、この値はInvalidateMeasureが偽となる使用することができます。
3.達成するために
リサイズアレンジ使用する必要があるので、上記のこれらの概念を理解するだけでは十分ではありません。リサイズ原理のControlTemplate再レイアウトサイズ変更要求がInnerContentControlのサイズを変更ContentControlに(InnerContentControl)を含む、リサイズが徐々にContentHeightリサイズとContentWidth特性を変更するためにストーリーボード、InnerContentControl.DesiredSize最終値を開始、Reszier簡単です。
DoubleAnimation heightAnimation;
DoubleAnimation widthAnimation;
if (Animation != null)
{
heightAnimation = Animation.Clone();
Storyboard.SetTarget(heightAnimation, this);
Storyboard.SetTargetProperty(heightAnimation, new PropertyPath(ContentHeightProperty));
widthAnimation = Animation.Clone();
Storyboard.SetTarget(widthAnimation, this);
Storyboard.SetTargetProperty(widthAnimation, new PropertyPath(ContentWidthProperty));
}
else
{
heightAnimation = _defaultHeightAnimation;
widthAnimation = _defaultWidthAnimation;
}
heightAnimation.From = ActualHeight;
heightAnimation.To = InnerContentControl.DesiredSize.Height;
widthAnimation.From = ActualWidth;
widthAnimation.To = InnerContentControl.DesiredSize.Width;
_resizingStoryboard.Children.Clear();
_resizingStoryboard.Children.Add(heightAnimation);
_resizingStoryboard.Children.Add(widthAnimation);
そしてContentWidth InvalidateMeasure()要求の再配置、MeasureOverride ContentWidthと戻り値のContentHeightを呼び出すContentHeight変更。リサイズこのサイズは徐々にアニメーションを実現するために進行ストーリーボードによって異なります。
protected override Size MeasureOverride(Size constraint)
{
if (_isResizing)
return new Size(ContentWidth, ContentHeight);
if (_isInnerContentMeasuring)
{
_isInnerContentMeasuring = false;
ChangeSize(true);
}
return base.MeasureOverride(constraint);
}
private void ChangeSize(bool useAnimation)
{
if (InnerContentControl == null)
{
return;
}
if (useAnimation == false)
{
ContentHeight = InnerContentControl.ActualHeight;
ContentWidth = InnerContentControl.ActualWidth;
}
else
{
if (_isResizing)
{
ResizingStoryboard.Stop();
}
_isResizing = true;
ResizingStoryboard.Begin();
}
}
次のように単にアニメーションエクスパンダの使用リサイズコントロールを追加することができ、効果は次のとおりです。
最後に、リサイズも提供しておりDoubleAnimation Animation
、次のようにプロパティが使用されているアニメーションを変更するために使用されます。
lt;kino:KinoResizer HorizontalContentAlignment=quot;Stretchquot;gt;
lt;kino:KinoResizer.Animationgt;
lt;DoubleAnimation BeginTime=quot;0:0:0quot;
Duration=quot;0:0:3quot;gt;
lt;DoubleAnimation.EasingFunctiongt;
lt;QuinticEase EasingMode=quot;EaseOutquot; /gt;
lt;/DoubleAnimation.EasingFunctiongt;
lt;/DoubleAnimationgt;
lt;/kino:KinoResizer.Animationgt;
lt;TextBox AcceptsReturn=quot;Truequot;
VerticalScrollBarVisibility=quot;Disabledquot; /gt;
lt;/kino:KinoResizergt;
4.おわりに
リサイズ制御私は通常、単独で使用しますが、ボタンなどの内部の他のコントロール、上のされません。
このため、制御性能の高くない、将来もAPIを改善することがあり、その後、プリミティブの名前空間に配置しました。
むかしむかし、多くの場合、多くの場合、レイアウトを処理するコードに現れる「レイアウトサイクル」このエラーに遭遇。最近、長い時間が、このエラーは発生しませんでした、おそらくWPFは堅牢になり、そしておそらく私のコードは、事前になります。しかし、かつて私はめったに測定を触れないし、コードを配置して、私はまた、測定の使用を推奨して気をつけて配置し、二度内気なかま。
5.リファレンス
FrameworkElement.MeasureOverride(サイズ)メソッド(System.Windows)マイクロソフトDocs.html
UIElement.DesiredSizeプロパティ(System.Windows)マイクロソフトDocs.html
UIElement.InvalidateMeasureメソッド(System.Windows)マイクロソフトのドキュメント
UIElement.IsMeasureValidプロパティ(System.Windows)マイクロソフトのドキュメント