윈도우 앱개발을 향하여

블로그 이미지
윈도우 10 스토어에 앱을 개발해 올리는 것을 목표로 하고 있습니다. 비전공자가 독학으로 시도하는 일이어서 얼마나 걸릴지 모르겠지만... 아무튼 목표는 그렇습니다!!
by 코딩하는 경제학도
  • Total hit
  • Today hit
  • Yesterday hit

Copyright

이 모든 내용은 Pluralsight에 Thomas Claudius Huber가 올린 'XAML Layout in Depth'라는 강의의 첫번째 챕터를 듣고 정리한 것입니다(https://app.pluralsight.com/library/courses/xaml-layout-in-depth/table-of-contents).


Content

1. Layout Basics 1

2. Layout Basics 2

3. Layout properties of Element

4. Panels

5. Transformations and Projections

6. Advanced Topics



Dependency Property

In XAML-based applications, there are multiple sources for a property. 예를 들어 Style을 통해 Button의 Width를 설정하고, Style안의 Style Trigger로 마우스가 올라갔을때의 Width를 설정할 수 있다. 이것만으로도 이미 two sources for that property를 가진 것이고, 더 많아질 수 있다(Template Trigger, Local Value(버튼에 직접 설정하는 것). Animation etc). For example, each Dependency property has also a default value. So a Dependency Property has different sources, but it can only have one current value. And this current value is dependent of the different sources. That's why the properties are called Dependency Properties.


DependencyObject

이렇게 다양한 source들을 통해 값이 지정될 수 있으므로 어떤 값을 선택할 것인지에 대한 logic이 DependencyObject class에 implement되어 있다(DependencyObject class는 UIElement의 base class이다). DependencyObject에는 SetValueGetValue라는 메소드가 있다. link


eg.  var btn = new Button();

btn.SetValue(Button.WidthProperty, 25.0);


//Button.WidthProperty는 DependencyProperty-Instance로써 it's of type DependencyProperty이다.

//이 DependencyProperty는 static field에 Property라는 suffix를 달고 저장되어있다.


Now behind the scenes, the SetValue call stores a Local Value for the Width property

그러나 GetValue를 호출하면 DependencyObject는 다양한 sources들을 뒤져서 적합한 값을 되돌려준다.



Attached Property

The special kind of a Dependency Property called Attached property is used extensively in layout.

An Attached Property is a property that you attach to any DependencyObject.


There are two kinds of Dependency properties

1. There are those Dependency properties that wrap SetValue and GetValue with a CLR-Property

var btn = new Button();

btn.SetValue(Button.WidthProperty, 25.0);


btn.Width = 25;   //calling SetValue method with Button.WidthProperty and value(25)


Those Dependency properties that use a CLR-Property as a wrapper we normally just call DependencyProperty.


2. The second kind of a Dependency property is wrapping the SetValue and GetValue method with static Set and Get methods

var btn = new Button();

btn.SetValue(Grid.RowProperty, 1); //pass in a Dependency property that is defined in another class(Grid.RowProperty)


Grid.SetRow(btn, 1);


Grid.RowProperty는 Grid class에 정의되있지만 can set a value for this property on a Button object(attach a value for this property to the Button object). For those properties, there exists static methods, in this case, the SetRow method defined in the Grid class. where you pass in your DependencyObject and the value. As with the CLR-Property, this static method just calls SetValue behind the scenes. So in this case, we call SetValue on the Button instance that is passed as a first parameter to the SetRow method.


Those properties that are attached to specific objects are called AttachedProperty.

For Attached properties, Attached-Property-Syntax for XAML exist


eg.  <Button Grid.Row="1"  .../>

Behind the scenes, the framework is calling the SetValue method on the Button object and passing in as a first parameter Grid.RowProperty and as a second parameter, the value 1.



#Two snippets for Dependency properties

propdp : for normal Dependency Property wrapping the SetValue, GetValue method with CLR-Property

propa : for Attached Property wrapping SetValue, GetValue with two static methods



eg.  public static double GetTop(DependencyObject obj)

{

          return (double)obj.GetValue(TopProperty);

}


public static void SetTop(DependencyObject obj, double value)

{

          obj.SetValue(TopProperty, value);

}


      //To create DependencyProperty, static RegisterAttached method is called

      public static readonly DependencyProperty TopProperty =

          DependencyProperty.RegisterAttached("Top", typeof(double), typeof(SimpleCanvas), new PropertyMetadata(0.0));

//(Name of the property, Type, the ownerclass of the DependencyProperty, Metadata(defines the default value for the Dependency Property)


protected override Size MeasureOverride(Size availableSize)

{

foreach (UIElement child in this.Children)

{

//이 샘플에선 SimpleCanvas의 크기계산엔 관심이 없으나

//child들이 Arrange되기 위해선 Measure를 호출해줄 필요가 있다.

child.Measure(availableSize);

}


return base.MeasureOverride(availableSize);

}


protected override Size ArrangeOverride(Size finalSize)

{

var location = new Point();

foreach (UIElement child in this.Children)

{

//var top = (double)child.GetValue(TopProperty);

//Child로부터 위와 같이 GetValue를 호출해 TopProperty 값을 얻어낼 수도 있지만

//이와 동일한 과정이 GetTop static method에 구현되있다. 따라서 GetTop method를 사용한다.

location.Y = GetTop(child);

child.Arrange(new Rect(location, child.DesiredSize));

}


return base.ArrangeOverride(finalSize);

}



<panel:SimpleCanvas>

    <Button Content="Hello" />

    <Button panel:SimpleCanvas.Top="10" Content="world!" />  //Button의 위치가 위에서 10만큼 아래로 조정된다.

</panel:SimpleCanvas>


//그러나 아직 AttachedProperty 값이 변경되었을 때 Control의 위치가 runtime에 즉시 욺겨지지는 않는다.



Layout Process Execution

The layout process is executed...

1. when an element is rendered its first time

2. when a child element was added or removed from the visual tree

3. when a specific dependency property has changed

4. when InvalidateMeasureInvalidateArrange methods is called on a UIElement

These methods will set the UIElement into an invalidate state and the framework will do a deferred layout process execution. (If you don't want that deferred execution, you can call the UpdateLayout method on your UIElement after you have called InvalidateMeasure or InvalidateArrange. The UpdateLayout method will force a layout process execution.)



Trigger the Layout Process from code

1. Using dependency property metadata (WPF only)

2. Using InvalidateArrage from PropertyChangedCallback (WPF, WinRT, Silverlight, Windows Phone... all XAML-based frameworks)



e.g. 1번의 경우는 DependencyProperty TomProperty = DependencyProperty.RegisterAttached의 4번째 parameter인 PropertyMetadata를 FrameworkPropertyMetadata로 바꾸고 FrameworkPropertyMetadataOption(위 경우엔 AffectParrentArrange)을 선택해 넘겨주면 된다.

(c.f. FrameworkPropertyMetadata는 OnPropertyChanged뿐 아니라 OnPropertyValueChanged 콜백함수도 추가할 수 있다.)


e.g.    //GetTop과 SetTop은 생략

  public static readonly DependencyProperty TopProperty = DependencyProperty.RegisterAttached("Top", typeof(double),                                                          typeof(SimpleCanvas), new PropertyMetadata(0.0, OnTopPropertyChanged));


        private static void OnTopPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

  //First parameter is not SimpleCanvas, its child of SimpleCanvas. (Setting of TopProperty on children)

  //From second parameter, we can access to new and old value and the DependencyProperty itself

        {

            if (d is FrameworkElement child)  //Get child from d as FrameworkElement

            {

                if (child.Parent is SimpleCanvas simpleCanvas)  //Get parent from child = SimpleCanvas

                {

   //We don't need to InvalidateMeasure in this case, we just want to arrange it again.

                    simpleCanvas.InvalidateArrange();


   //Make layout Update right away

                    simpleCanvas.UpdateLayout();

                }

            }

        }



Summary (생략)


출처

이 모든 내용은 Pluralsight에 Thomas Claudius Huber가 올린 'XAML Layout in Depth'라는 강의의 첫번째 챕터를 듣고 정리한 것입니다(https://app.pluralsight.com/library/courses/xaml-layout-in-depth/table-of-contents). 제가 정리한 것보다 더 많은 내용과 Demo를 포함하고 있으며 최종 Summary는 생략하겠습니다. Microsoft 지원을 통해 한달간 무료로 Pluralsight의 강의를 들으실 수도 있습니다.

AND

ARTICLE CATEGORY

분류 전체보기 (56)
Programming (45)
MSDN (4)
개발노트 (2)
reference (5)

RECENT ARTICLE

RECENT COMMENT

CALENDAR

«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

ARCHIVE