[WPF 사용자 지정 컨트롤 라이브러리]는 공정 레이아웃 WPF를 이해하고, 애니메이션 확장기를 추가 측정을 사용하여

원래는 : [WPF 사용자 지정 컨트롤 라이브러리]는 공정 레이아웃 WPF를 이해하고, 애니메이션 확장기를 추가 측정을 사용하여

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) 마이크로 소프트 문서

6. 소스

마스터에서 Kino.Toolkit.Wpf_Resizer

추천

출처www.cnblogs.com/lonelyxmas/p/11242108.html