1. 소개
이 도움말은 달성 될 수있는 콘텐츠 리사이 제어를 측정하여 두 단계 배치를 WPF UI 요소 및 도입을 설명한다.
나는 애니메이션을 수행하는 초보자에게 너무 많은 작업을하지 않는 것이 좋습니다,하지만, 애니메이션, 시각의 해당 라인에 사용자를 직접 사용자 경험을 향상시킬 수 있습니다. 예를 들어,이 애니메이션의 그림, 애니메이션뿐만 아니라, 내용의 높이를 변경할 때 동적으로 잘 생긴, 사용자 경험을 향상시키기 위해 유용 자신의 높이를 변경, 매우 일반적입니다. 불행히도, WPF 자체도 확장기가 확장 / 축소에는 애니메이션없고,이 점에서 기본적으로이 기능을 지원하지 않습니다. 이런 이유로 나는 내용의 크기를 (변경시 크기 크기 변경 제어를 변경하는 애니메이션 방식을 달성 할 수 있는 좋은 이름 추천 요청할 것을 생각 ). 사실, 실버 라이트에서 정직 툴킷 이식 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 레이아웃은 실질적으로 제 레이아웃 요소 재귀 레이아웃을 구현 정렬 후 모든 자식 요소 측정 값에 필요한 크기를 계산 측정하고 두 단계로 정렬.
StackPanel을 위해, 예를 들어, 필요 StackPanel의 레이아웃, 처음 볼 수 있습니다 얼마나 많은 공간이 알아야하고 그들이 필요로하는 아동 얼마나 많은 공간의 모든 아이를 물어 사용할 수있는 공간을 사용합니다, 이것은 측정, 공간을 필요로하는 모든 자식 요소 자신의 서브 - 소자의 레이아웃 논리 후에 배열 인 설치의 실제 크기와 위치를 측정한다.
StackPanel의 레이아웃을 다시하는 경우 (예를 들면, 사이즈 변경 StackPanel에), 2 단계 공정은 StackPanel의 레이아웃을 반복한다이 때. StackPanel의의 자식 요소가 레이아웃을 다시해야하는 경우는 StackPanel의 레이아웃을 다시 통보해야합니다.
2.2 MeasureOverride 함수
의 MesureOverride 파생 클래스의 오버라이드는 서브 - 소자의 배치의 크기를 측정하기 위해 필요했다. 논의하기 위해 자신과 자식 요소 후 다시 사용할 수있는 공간 부모 요소는 단순히 우리가 부모 요소의 크기를 말할 필요가 자신에게 있습니다.
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. 달성하기
리사이는 정렬 사용할 필요가 있으므로 위의 이러한 개념을 이해하는 것만으로는 충분하지. 리사이 원리 재 레이아웃 요청 크기 변경은 상기 InnerContentControl의 크기를 변경하는 크기 변경 서서히 ContentHeight 크기 변경과 ContentWidth 특성을 변경하는 스토리 보드 InnerContentControl.DesiredSize 최종 값을 시작할 때 Reszier가 된 ControlTemplate하기, ContentControl을 (InnerContentControl)가 포함되어, 간단
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 () 요청 재 레이아웃의 MesureOverride 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) 마이크로 소프트 문서