■ ExpressionAnimation 클래스를 사용해 서로 상대적인 엘리먼트 위치를 설정하는 방법을 보여준다.
▶ DoubleToThicknessConverter.cs
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
using System; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Data; namespace TestProject { /// <summary> /// 실수→두께 변환자 /// </summary> public class DoubleToThicknessConverter : IValueConverter { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 변환하기 - Convert(sourceValue, targetType, parameter, language) /// <summary> /// 변환하기 /// </summary> /// <param name="sourceValue">소스 값</param> /// <param name="targetType">타겟 타입</param> /// <param name="parameter">매개 변수</param> /// <param name="language">언어</param> /// <returns>변환 값</returns> public object Convert(object sourceValue, Type targetType, object parameter, string language) { if(sourceValue is double?) { return new Thickness((double)sourceValue); } return false; } #endregion #region 역변환하기 - ConvertBack(sourceValue, targetType, parameter, language) /// <summary> /// 역변환하기 /// </summary> /// <param name="sourceValue">소스 값</param> /// <param name="targetType">타겟 타입</param> /// <param name="parameter">매개 변수</param> /// <param name="language">언어</param> /// <returns>역변환 값</returns> public object ConvertBack(object sourceValue, Type targetType, object parameter, string language) { throw new NotImplementedException(); } #endregion } } |
▶ MainPage.xaml
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
<?xml version="1.0" encoding="utf-8"?> <Page x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:TestProject" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" FontFamily="나눔고딕코딩" FontSize="16"> <Page.Resources> <local:DoubleToThicknessConverter x:Key="DoubleToThicknessConverterKey" /> </Page.Resources> <Grid Margin="10"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="10" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Grid Grid.Column="0" HorizontalAlignment="Left"> <TextBlock Name="targetTextBlock" Margin="{x:Bind marginSlider.Value, Converter={StaticResource DoubleToThicknessConverterKey}, Mode=OneWay}" Width="300" TextWrapping="WrapWholeWords" FontSize="{x:Bind fontSizeSlider.Value, Mode=OneWay}" Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." /> <Popup Name="popup" Margin="5"> <Grid MinWidth="50" MaxWidth="200" MinHeight="50" BorderBrush="{ThemeResource SystemControlForegroundChromeGrayBrush}" BorderThickness="2" Background="{ThemeResource FlyoutBackgroundThemeBrush}"> <TextBlock Style="{ThemeResource CaptionTextBlockStyle}" VerticalAlignment="Center" Margin="5" TextWrapping="WrapWholeWords" Text="I am always right aligned center to the target." /> </Grid> </Popup> </Grid> <StackPanel Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center"> <Slider Name="fontSizeSlider" Header="Change font size" Minimum="12" Maximum="24" /> <Slider Name="marginSlider" Margin="0 10 0 0" Header="Change text margin" Minimum="0" Maximum="100" /> </StackPanel> </Grid> </Page> |
▶ MainPage.xaml.cs
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
using Microsoft.UI.Composition; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; namespace TestProject { /// <summary> /// 메인 페이지 /// </summary> public sealed partial class MainPage : Page { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 합성자 /// </summary> private Compositor compositor = CompositionTarget.GetCompositorForCurrentThread(); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainPage() /// <summary> /// 생성자 /// </summary> public MainPage() { InitializeComponent(); Loaded += Page_Loaded; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private //////////////////////////////////////////////////////////////////////////////// Event #region 페이지 로드시 처리하기 - Page_Loaded(sender, e) /// <summary> /// 페이지 로드시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void Page_Loaded(object sender, RoutedEventArgs e) { ExpressionAnimation animation = this.compositor.CreateExpressionAnimation(); animation.Expression = "Vector3(source.ActualOffset.X + source.ActualSize.X, source.ActualOffset.Y + source.ActualSize.Y / 2 - 25, 0)"; animation.Target = "Translation"; animation.SetExpressionReferenceParameter("source", this.targetTextBlock); this.popup.StartAnimation(animation); this.popup.IsOpen = true; } #endregion } } |