zoukankan      html  css  js  c++  java
  • 背水一战 Windows 10 (72)

    [源码下载]


    背水一战 Windows 10 (72) - 控件(控件基类): UIElement - UIElement 的位置, UIElement 的布局, UIElement 的其他特性



    作者:webabcd


    介绍
    背水一战 Windows 10 之 控件(控件基类 - UIElement)

    • 获取 UIElement 的位置
    • UIElement 的布局相关(Measure, Arrange)
    • UIElement 的非完整像素布局(UseLayoutRounding)
    • UIElement 的其他特性(Visibility, Opacity, CacheMode)



    示例
    1、演示如何获取 UIElement 的位置
    Controls/BaseControl/UIElementDemo/TransformToVisualDemo.xaml

    <Page
        x:Class="Windows10.Controls.BaseControl.UIElementDemo.TransformToVisualDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Windows10.Controls.BaseControl.UIElementDemo"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="10 0 10 10">
    
                <Grid HorizontalAlignment="Left" VerticalAlignment="Top" Margin="5">
                    <Rectangle Name="rectangle1" Width="300" Height="200" Fill="Red" />
                    <Rectangle Name="rectangle2" Width="150" Height="100" Fill="Green" />
                </Grid>
    
                <TextBlock Name="lblMsg" Margin="5" />
    
            </StackPanel>
        </Grid>
    </Page>

    Controls/BaseControl/UIElementDemo/TransformToVisualDemo.xaml.cs

    /*
     * UIElement - UIElement(继承自 DependencyObject, 请参见 /Controls/BaseControl/DependencyObjectDemo/)
     *     TransformToVisual(UIElement visual) - 返回相对于指定 UIElement 原点(左上角顶点)的 GeneralTransform 类型的对象,传 null 值则为相对于 app 原点(左上角顶点)
     *     
     *     
     * GeneralTransform
     *     Point TransformPoint(Point point) - 获取相对于指定位置的位置
     *     
     *     
     * 本例用于演示如何获取 UIElement 的位置
     */
    
    using System;
    using Windows.Foundation;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Media;
    
    namespace Windows10.Controls.BaseControl.UIElementDemo
    {
        public sealed partial class TransformToVisualDemo : Page
        {
            public TransformToVisualDemo()
            {
                this.InitializeComponent();
    
                this.Loaded += TransformToVisualDemo_Loaded;
            }
    
            void TransformToVisualDemo_Loaded(object sender, RoutedEventArgs e)
            {
                Demo1();
                Demo2();
            }
    
            // 演示如何获取 UIElement 相对于 app 原点(左上角顶点)的位置
            private void Demo1()
            {
                GeneralTransform generalTransform = rectangle1.TransformToVisual(null); // 获取 rectangle1 相对于 app 原点(左上角顶点)的 GeneralTransform
                Point point = generalTransform.TransformPoint(new Point(0, 0)); // rectangle1 的原点(左上角顶点)相对于屏幕 0,0 点的位置
    
                lblMsg.Text += "红色矩形的原点(左上角顶点)相对于屏幕的原点(左上角顶点)的位置:" + point.ToString();
                lblMsg.Text += Environment.NewLine;
    
            }
    
            // 演示如何获取 UIElement 相对于另一个 UIElement 原点(左上角顶点)的位置
            private void Demo2()
            {
                GeneralTransform generalTransform = rectangle1.TransformToVisual(rectangle2); // 获取 rectangle1 相对于 rectangle2 原点(左上角顶点)的 GeneralTransform
                Point point = generalTransform.TransformPoint(new Point(0, 0)); // rectangle1 的原点(左上角顶点)相对于 rectangle2 的原点(左上角顶点)的位置
    
                lblMsg.Text += "红色矩形的原点(左上角顶点)相对于绿色矩形的原点(左上角顶点)的位置:" + point.ToString();
            }
        }
    }


    2、演示 UIElement 的布局相关
    Controls/BaseControl/UIElementDemo/LayoutDemo.xaml

    <Page
        x:Class="Windows10.Controls.BaseControl.UIElementDemo.LayoutDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Windows10.Controls.BaseControl.UIElementDemo"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="10 0 10 10">
                
                <StackPanel Name="stackPanel" Margin="1 2 3 4" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" Background="Orange">
                    <Rectangle Name="rectangle1" Fill="White" Width="100" Height="100" />
                </StackPanel>
                
                <TextBlock Name="lblMsg" Margin="5" />
                
            </StackPanel>
        </Grid>
    </Page>

    Controls/BaseControl/UIElementDemo/LayoutDemo.xaml.cs

    /*
     * UIElement - UIElement(继承自 DependencyObject, 请参见 /Controls/BaseControl/DependencyObjectDemo/)
     *     Measure(), Arrange(), InvalidateMeasure(), InvalidateArrange() - 参见 /MyControls/MyControl2.cs
     *     DesiredSize - 获取通过 Measure() 计算后得到的期望尺寸
     *     RenderSize - 获取通过 Arrange() 计算后得到的呈现尺寸
     *     UpdateLayout() - 相当于依次调用 InvalidateMeasure() 和 InvalidateArrange(),然后同步等待结果,而 InvalidateMeasure() 和 InvalidateArrange() 本身是异步处理的
     *    
     * 
     * 注:
     * 1、uwp 的 layout 是一个递归系统,更多说明请参见 /MyControls/MyControl2.cs
     * 2、InvalidateMeasure() 就是递归调用自己和子辈门的 Measure()
     * 3、InvalidateArrange() 就是递归调用自己和子辈门的 Arrange()
     *    
     * 
     * 本例用于演示 UIElement 的布局相关
     */
    
    using System;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    
    namespace Windows10.Controls.BaseControl.UIElementDemo
    {
        public sealed partial class LayoutDemo : Page
        {
            public LayoutDemo()
            {
                this.InitializeComponent();
    
                this.Loaded += LayoutDemo_Loaded;
            }
    
            private void LayoutDemo_Loaded(object sender, RoutedEventArgs e)
            {
                lblMsg.Text += stackPanel.DesiredSize.ToString(); // 204,106(期望尺寸,是包括 margin 的)
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += stackPanel.RenderSize.ToString(); // 200,100(呈现尺寸,是不包括 margin 的)
                lblMsg.Text += Environment.NewLine;
    
                // 更改外观
                stackPanel.Margin = new Thickness(5);
                rectangle1.Height = 300;
    
                // 更改外观后,布局系统会自动调用 InvalidateMeasure() 和 InvalidateArrange(),但是这是个异步的过程
                // 所以此处获取到的 DesiredSize 和 RenderSize 仍然是更改外观之前的值
                lblMsg.Text += stackPanel.DesiredSize.ToString(); // 204,106(期望尺寸,是包括 margin 的)
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += stackPanel.RenderSize.ToString(); // 200,100(呈现尺寸,是不包括 margin 的)
                lblMsg.Text += Environment.NewLine;
    
                // 如果想要同步知道结果的话就调用 UpdateLayout()
                stackPanel.UpdateLayout();
    
                // 所以此处获取到的 DesiredSize 和 RenderSize 为更改外观之后的值
                lblMsg.Text += stackPanel.DesiredSize.ToString(); // 210,310(期望尺寸,是包括 margin 的)
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += stackPanel.RenderSize.ToString(); // 200,300(呈现尺寸,是不包括 margin 的)
            }
        }
    }


    3、演示 UIElement 的 UseLayoutRounding 的应用
    Controls/BaseControl/UIElementDemo/UseLayoutRoundingDemo.xaml

    <Page
        x:Class="Windows10.Controls.BaseControl.UIElementDemo.UseLayoutRoundingDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Windows10.Controls.BaseControl.UIElementDemo"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="10 0 10 10">
    
                <!--
                    UseLayoutRounding - 是否使用完整像素布局。默认值为 true
                        举例说明:如果设置了某个元素的 Margin="1.6"(非完整像素),那么
                        1、当 UseLayoutRounding="true" 时,则设置为 Margin="1.6" 的元素的各个方向的 Margin 是不相等的,但是显示清晰
                        2、当 UseLayoutRounding="false" 时,则设置为 Margin="1.6" 的元素的各个方向的 Margin 是相等的,但是显示不清晰
                
                    注:UseLayoutRounding 是会自动继承的,即子元素会继承父元素的 UseLayoutRounding 设置
                -->
                <Grid Width="200" Height="200" Margin="5" HorizontalAlignment="Left">
                    <Border BorderBrush="Black" Background="White" BorderThickness="1"></Border>
                    <Border BorderBrush="Black" Background="White" BorderThickness="1" Margin="1.6" UseLayoutRounding="True"></Border>
                </Grid>
    
                <Grid Width="200" Height="200" Margin="5" HorizontalAlignment="Left">
                    <Border BorderBrush="Black" Background="White" BorderThickness="1"></Border>
                    <Border BorderBrush="Black" Background="White" BorderThickness="1" Margin="1.6" UseLayoutRounding="False"></Border>
                </Grid>
    
            </StackPanel>
        </Grid>
    </Page>

    Controls/BaseControl/UIElementDemo/UseLayoutRoundingDemo.xaml.cs

    /*
     * UIElement - UIElement(继承自 DependencyObject, 请参见 /Controls/BaseControl/DependencyObjectDemo/)
     *     UseLayoutRounding - 是否使用完整像素布局。默认值为 true
     *     
     *     
     * 本例用于演示 UIElement 的 UseLayoutRounding 的应用
     */
    
    using Windows.UI.Xaml.Controls;
    
    namespace Windows10.Controls.BaseControl.UIElementDemo
    {
        public sealed partial class UseLayoutRoundingDemo : Page
        {
            public UseLayoutRoundingDemo()
            {
                this.InitializeComponent();
            }
        }
    }


    4、演示 UIElement 的其他特性
    Controls/BaseControl/UIElementDemo/OthersDemo.xaml

    <Page
        x:Class="Windows10.Controls.BaseControl.UIElementDemo.OthersDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Windows10.Controls.BaseControl.UIElementDemo"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="5">
    
                <Rectangle Fill="Orange" Width="100" Height="100" Margin="5" Visibility="Collapsed" />
                <Rectangle Fill="Orange" Width="100" Height="100" Margin="5" Opacity="0.5" CacheMode="BitmapCache" />
    
            </StackPanel>
        </Grid>
    </Page>

    Controls/BaseControl/UIElementDemo/OthersDemo.xaml.cs

    /*
     * UIElement - UIElement(继承自 DependencyObject, 请参见 /Controls/BaseControl/DependencyObjectDemo/)
     *     Visibility - 可见性
     *         Visible - 显示
     *         Collapsed - 不显示,且不占位
     *     Opacity - 不透明度(0.0 - 1.0 之间,默认值为 1.0)
     *     CacheMode - 缓存模式
     *         null - 默认值
     *         BitmapCache - 用 GPU 渲染 RenderTransform 和 Opacity
     *             如果 RenderTransform 或 Opacity 使用了 storyboard 动画的话,动画一律将变为 Dependent Animation 而不是 Independent Animation,这样性能就会变差。一般来说不用设置成 BitmapCache 模式
     *     
     *     
     * 本例用于演示 UIElement 的其他特性
     */
    
    using Windows.UI.Xaml.Controls;
    
    namespace Windows10.Controls.BaseControl.UIElementDemo
    {
        public sealed partial class OthersDemo : Page
        {
            public OthersDemo()
            {
                this.InitializeComponent();
    
                // this.Visibility = Visibility.Collapsed;
                // this.Opacity = 0.5;
                // this.CacheMode = null;
                // this.CacheMode = new BitmapCache();
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    DateTime类型的一个Bug
    无痛苦的软件维护——被遗忘的需求
    完全命令行.NET开发
    无痛苦的软件维护——文档和代码
    .NET初学者架构设计指南(一)Hello world的时代
    NGOSS的一点简单概念
    软件的逻辑层次
    VSTS for Testers学习笔记目录
    How Google Tests Software (出书,停止更新)
    推荐——《浪潮之巅》(据传稍后会出书,停止更新)
  • 原文地址:https://www.cnblogs.com/webabcd/p/7824758.html
Copyright © 2011-2022 走看看