debugging 在VS 2022中检查WinUI 3应用程序的实时可视化树查看器中的PopupRoot?

sc4hvdpw  于 2023-01-21  发布在  其他
关注(0)|答案(1)|浏览(176)

在使用 WinUI 3 应用程序和 XAML 时,我一直使用 VS 2022 中的***实时可视树***查看器和***实时属性资源管理器***工具。检查“常规”可视树中的元素并与之交互(从RootScrollViewer开始,见附图)很容易,但我似乎不能对PopupsFlyouts做同样的事情,其根(PopupRoot)与普通UI树不同。

此屏幕截图显示了DatePickerFlyout的展开PopupRoot。但我无法展开任何LoopingSelector元素或查看PopupRoot中任何元素的*Live Properties,因为Flyout一旦失去焦点就会关闭(PopupRoot变为空)。
有没有什么方法可以让我以与RootScrollViewer树相同或相似的方式检查PopupRoot树及其元素属性?也许是我忽略了一个设置?或者有人知道其他工具可以帮助我在 WinUI 3 应用程序中实现这一点?
谢谢你的建议。

nbewdwxp

nbewdwxp1#

我使用的是普通DatePicker的自定义版本,这样我就可以使用OnApplyTemplate()Measure()Styles直接来自 WindowsAppSDK v1.2.22116Generic.xaml文件,名称经过了修改(并对一些Width属性进行了轻微更改)。

自定义日期选取器.cs

using Microsoft.UI.Xaml.Controls;
using CommunityToolkit.Mvvm.ComponentModel;

namespace TestDatePicker.Classes;

[ObservableObject]
public partial class CustomDatePicker : DatePicker
{
    [ObservableProperty] private Button _flyoutButton;
    [ObservableProperty] private ColumnDefinition _dayColumn;
    [ObservableProperty] private ColumnDefinition _monthColumn;
    [ObservableProperty] private ColumnDefinition _yearColumn;
    [ObservableProperty] private TextBlock _dayTextBlock;
    [ObservableProperty] private TextBlock _monthTextBlock;
    [ObservableProperty] private TextBlock _yearTextBlock;
    [ObservableProperty] private DatePickerFlyoutPresenter _flyoutPresenter;

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        FlyoutButton = GetTemplateChild("FlyoutButton") as Button;
        if (FlyoutButton == null) { return; }

        DayColumn = GetTemplateChild("DayColumn") as ColumnDefinition;
        if (DayColumn == null) { return; }
        MonthColumn = GetTemplateChild("MonthColumn") as ColumnDefinition;
        if (MonthColumn == null) { return; }
        YearColumn = GetTemplateChild("YearColumn") as ColumnDefinition;
        if (YearColumn == null) { return; }

        DayTextBlock = GetTemplateChild("DayTextBlock") as TextBlock;
        if (DayTextBlock == null) { return; }
        MonthTextBlock = GetTemplateChild("MonthTextBlock") as TextBlock;
        if (MonthTextBlock == null) { return; }
        YearTextBlock = GetTemplateChild("YearTextBlock") as TextBlock;
        if (YearTextBlock == null) { return; }
    }
}

自定义日期选择器.xaml(包括Styles用于:(一名男子六名十一名一名男子七名一名一名一名男子八名一名一名一名九名一名一名一名男子十名一名一名一名一名一名一名一名一名一名一名十二名一名一名一名一名十三名)

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:primitives="using:Microsoft.UI.Xaml.Controls.Primitives"
    xmlns:helpers="using:TestDatePicker.Helpers">

    <Thickness x:Key="DatePickerBorderThemeThickness">1</Thickness>

    <Style x:Key="CustomDatePickerFlyoutButtonStyle" TargetType="Button">
        <Setter Property="helpers:BindingHelper.StyleLoaded" Value="CustomDatePickerFlyoutButtonStyle"/>
        <Setter Property="ElementSoundMode" Value="FocusOnly" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid>

                        <VisualStateManager.VisualStateGroups...>

                        <ContentPresenter x:Name="ContentPresenter" 
                                          Background="{TemplateBinding Background}" 
                                          Foreground="{TemplateBinding Foreground}" 
                                          BorderBrush="{TemplateBinding BorderBrush}" 
                                          BorderThickness="{TemplateBinding BorderThickness}" 
                                          Content="{TemplateBinding Content}" 
                                          HorizontalContentAlignment="Stretch" 
                                          VerticalContentAlignment="Stretch" 
                                          AutomationProperties.AccessibilityView="Raw" 
                                          CornerRadius="{TemplateBinding CornerRadius}" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="CustomDatePickerStyle" TargetType="DatePicker" BasedOn="{StaticResource DefaultDatePickerStyle}">
        <!--<Setter Property="helpers:BindingHelper.StyleLoaded" Value="CustomDatePickerStyle"/>-->
        <Setter Property="Orientation" Value="Horizontal" />
        <Setter Property="FocusVisualMargin" Value="0" />
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
        <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
        <Setter Property="Background" Value="{ThemeResource DatePickerButtonBackground}" />
        <Setter Property="Foreground" Value="{ThemeResource DatePickerButtonForeground}" />
        <Setter Property="BorderBrush" Value="{ThemeResource DatePickerButtonBorderBrush}" />
        <Setter Property="BorderThickness" Value="{ThemeResource DatePickerBorderThemeThickness}" />
        <Setter Property="HorizontalAlignment" Value="Left" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
        <Setter Property="FocusVisualMargin" Value="-3" />
        <Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="DatePicker">
                    <Grid x:Name="LayoutRoot" Margin="{TemplateBinding Padding}">

                        <VisualStateManager.VisualStateGroups...>

                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <ContentPresenter x:Name="HeaderContentPresenter"
                            Grid.Row="0"
                            Content="{TemplateBinding Header}"
                            ContentTemplate="{TemplateBinding HeaderTemplate}"
                            Foreground="{ThemeResource DatePickerHeaderForeground}"
                            Margin="{ThemeResource DatePickerTopHeaderMargin}"
                            MaxWidth="{ThemeResource DatePickerThemeMaxWidth}"
                            TextWrapping="Wrap"
                            HorizontalAlignment="Stretch"
                            VerticalAlignment="Top"
                            Visibility="Collapsed"
                            AutomationProperties.AccessibilityView="Raw" />
                        <Button x:Name="FlyoutButton" 
                                Grid.Row="1" 
                                Style="{StaticResource CustomDatePickerFlyoutButtonStyle}" 
                                Background="{TemplateBinding Background}" 
                                Foreground="{TemplateBinding Foreground}" 
                                BorderBrush="{TemplateBinding BorderBrush}" 
                                BorderThickness="{TemplateBinding BorderThickness}" 
                                IsEnabled="{TemplateBinding IsEnabled}" 
                                HorizontalAlignment="Stretch" 
                                HorizontalContentAlignment="Stretch" 
                                VerticalAlignment="Top" 
                                FocusVisualMargin="{TemplateBinding FocusVisualMargin}" 
                                UseSystemFocusVisuals="{TemplateBinding UseSystemFocusVisuals}" 
                                CornerRadius="{TemplateBinding CornerRadius}">
                            <!--MinWidth="{StaticResource DatePickerThemeMinWidth}" 
                        MaxWidth="{StaticResource DatePickerThemeMaxWidth}"-->
                            <Grid x:Name="FlyoutButtonContentGrid">

                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" x:Name="DayColumn" />
                                    <ColumnDefinition Width="Auto" x:Name="FirstSpacerColumn" />
                                    <ColumnDefinition Width="*" x:Name="MonthColumn" />
                                    <ColumnDefinition Width="Auto" x:Name="SecondSpacerColumn" />
                                    <ColumnDefinition Width="*" x:Name="YearColumn" />
                                </Grid.ColumnDefinitions>
                                <!-- Code must set the Grid.Column numbers for the TextBoxes based on culture. It also sets the Text. -->
                                <TextBlock x:Name="DayTextBlock" Text="dd"
                                           TextAlignment="Center" 
                                           Padding="{ThemeResource DatePickerHostPadding}" 
                                           FontFamily="{TemplateBinding FontFamily}" 
                                           FontWeight="{TemplateBinding FontWeight}" 
                                           FontSize="{TemplateBinding FontSize}" 
                                           AutomationProperties.AccessibilityView="Raw" />
                                <TextBlock x:Name="MonthTextBlock" Text="mm" 
                                           TextAlignment="Center" 
                                           Padding="{ThemeResource DatePickerHostPadding}" 
                                           FontFamily="{TemplateBinding FontFamily}" 
                                           FontWeight="{TemplateBinding FontWeight}" 
                                           FontSize="{TemplateBinding FontSize}" 
                                           AutomationProperties.AccessibilityView="Raw" />
                                <TextBlock x:Name="YearTextBlock" Text="yy" 
                                           TextAlignment="Center" 
                                           Padding="{ThemeResource DatePickerHostPadding}" 
                                           FontFamily="{TemplateBinding FontFamily}" 
                                           FontWeight="{TemplateBinding FontWeight}" 
                                           FontSize="{TemplateBinding FontSize}" 
                                           AutomationProperties.AccessibilityView="Raw" />
                                <Rectangle x:Name="FirstPickerSpacing" 
                                           Fill="{ThemeResource DatePickerSpacerFill}" 
                                           HorizontalAlignment="Center" 
                                           Width="{ThemeResource DatePickerSpacerThemeWidth}" 
                                           Grid.Column="1" />
                                <Rectangle x:Name="SecondPickerSpacing" 
                                           Fill="{ThemeResource DatePickerSpacerFill}" 
                                           HorizontalAlignment="Center" 
                                           Width="{ThemeResource DatePickerSpacerThemeWidth}" 
                                           Grid.Column="3" />
                            </Grid>
                        </Button>

                    </Grid>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style TargetType="DatePickerFlyoutPresenter" BasedOn="{StaticResource CustomDatePickerFlyoutPresenterStyle}"/>

    <Style x:Key="CustomDatePickerFlyoutPresenterStyle" TargetType="DatePickerFlyoutPresenter">
        <!--<Setter Property="helpers:BindingHelper.StyleLoaded" Value="CustomDatePickerFlyoutPresenterStyle"/>-->
        <!--<Setter Property="Width" Value="296" />
        <Setter Property="MinWidth" Value="296" />-->
        <Setter Property="MaxHeight" Value="398" />
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
        <Setter Property="FontWeight" Value="Normal" />
        <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
        <Setter Property="Background" Value="{ThemeResource DatePickerFlyoutPresenterBackground}" />
        <Setter Property="AutomationProperties.AutomationId" Value="DatePickerFlyoutPresenter" />
        <Setter Property="BorderBrush" Value="{ThemeResource DatePickerFlyoutPresenterBorderBrush}" />
        <Setter Property="BorderThickness" Value="{ThemeResource DateTimeFlyoutBorderThickness}" />
        <Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="DatePickerFlyoutPresenter">
                    <Border x:Name="Background"
                              Background="{TemplateBinding Background}"
                              BorderBrush="{TemplateBinding BorderBrush}"
                              BorderThickness="{TemplateBinding BorderThickness}"
                              CornerRadius="{TemplateBinding CornerRadius}"
                              Padding="{ThemeResource DateTimeFlyoutBorderPadding}"
                              MaxHeight="398">
                        <Grid x:Name="ContentPanel">

                            <Grid.RowDefinitions>
                                <RowDefinition Height="*" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <Grid>
                                <Grid x:Name="PickerHostGrid">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="*" x:Name="DayColumn" />
                                        <ColumnDefinition Width="Auto" x:Name="FirstSpacerColumn" />
                                        <ColumnDefinition Width="*" x:Name="MonthColumn" />
                                        <ColumnDefinition Width="Auto" x:Name="SecondSpacerColumn" />
                                        <ColumnDefinition Width="*" x:Name="YearColumn" />
                                    </Grid.ColumnDefinitions>
                                    <Rectangle x:Name="FirstPickerSpacing" Fill="{ThemeResource DatePickerFlyoutPresenterSpacerFill}" HorizontalAlignment="Center" Width="{ThemeResource DatePickerSpacerThemeWidth}" Canvas.ZIndex="10000" Grid.Column="1" />
                                    <Rectangle x:Name="SecondPickerSpacing" Fill="{ThemeResource DatePickerFlyoutPresenterSpacerFill}" HorizontalAlignment="Center" Width="{ThemeResource DatePickerSpacerThemeWidth}" Canvas.ZIndex="10000" Grid.Column="3" />
                                    <Grid x:Name="HighlightRect" Canvas.ZIndex="9999" Background="{ThemeResource DatePickerFlyoutPresenterHighlightFill}" CornerRadius="{TemplateBinding CornerRadius}" Grid.Column="0" Grid.ColumnSpan="5" VerticalAlignment="Center" Height="{ThemeResource DatePickerFlyoutPresenterHighlightHeight}" Margin="4,2,4,2" IsHitTestVisible="false" />
                                    <primitives:MonochromaticOverlayPresenter Canvas.ZIndex="10000"
                                              Grid.Column="{Binding ElementName=DayLoopingSelector,Path=(Grid.Column)}"
                                              SourceElement="{Binding ElementName=DayLoopingSelector}" 
                                              ReplacementColor="{ThemeResource DatePickerFlyoutPresenterHighlightForegroundColor}" 
                                              Height="{ThemeResource DatePickerFlyoutPresenterHighlightHeight}" 
                                              VerticalAlignment="Center" 
                                              IsHitTestVisible="false" />
                                    <primitives:MonochromaticOverlayPresenter Canvas.ZIndex="10000"
                                              Grid.Column="{Binding ElementName=MonthLoopingSelector,Path=(Grid.Column)}" 
                                              SourceElement="{Binding ElementName=MonthLoopingSelector}" 
                                              ReplacementColor="{ThemeResource DatePickerFlyoutPresenterHighlightForegroundColor}" 
                                              Height="{ThemeResource DatePickerFlyoutPresenterHighlightHeight}" 
                                              VerticalAlignment="Center" 
                                              IsHitTestVisible="false" />
                                    <primitives:MonochromaticOverlayPresenter Canvas.ZIndex="10000" 
                                              Grid.Column="{Binding ElementName=YearLoopingSelector,Path=(Grid.Column)}" 
                                              SourceElement="{Binding ElementName=YearLoopingSelector}" 
                                              ReplacementColor="{ThemeResource DatePickerFlyoutPresenterHighlightForegroundColor}" 
                                              Height="{ThemeResource DatePickerFlyoutPresenterHighlightHeight}" 
                                              VerticalAlignment="Center" 
                                              IsHitTestVisible="false" />

                                </Grid>
                            </Grid>
                            <Grid Grid.Row="1" Height="{ThemeResource DatePickerFlyoutPresenterAcceptDismissHostGridHeight}" x:Name="AcceptDismissHostGrid">

                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>
                                <Rectangle Height="{ThemeResource DatePickerSpacerThemeWidth}" VerticalAlignment="Top" Fill="{ThemeResource DatePickerFlyoutPresenterSpacerFill}" Grid.ColumnSpan="2" />
                                <Button x:Name="AcceptButton" Grid.Column="0" Content="&#xE8FB;" FontFamily="{ThemeResource SymbolThemeFontFamily}" FontSize="16" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="{StaticResource DatePickerFlyoutPresenterAcceptMargin}" Padding="4" Style="{StaticResource DateTimePickerFlyoutButtonStyle}" />
                                <Button x:Name="DismissButton" Grid.Column="1" Content="&#xE711;" FontFamily="{ThemeResource SymbolThemeFontFamily}" FontSize="16" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="{StaticResource DatePickerFlyoutPresenterDismissMargin}" Padding="4" Style="{StaticResource DateTimePickerFlyoutButtonStyle}" />
                            </Grid>

                        </Grid>
                    </Border>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <!-- Default style for Windows.UI.Xaml.Controls.Primitives.LoopingSelector -->
    <Style TargetType="LoopingSelector" BasedOn="{StaticResource DefaultLoopingSelectorStyle}" />

    <Style TargetType="LoopingSelector" x:Key="DefaultLoopingSelectorStyle">
        <!--<Setter Property="helpers:BindingHelper.StyleLoaded" Value="DefaultLoopingSelectorStyle"/>-->
        <Setter Property="ShouldLoop" Value="True" />
        <Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
        <Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}" />
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <StackPanel VerticalAlignment="Center">
                        <TextBlock Text="{Binding PrimaryText}" FontFamily="{ThemeResource ContentControlThemeFontFamily}"/>
                    </StackPanel>
                </DataTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Control">
                    <Grid>

                        <VisualStateManager.VisualStateGroups...>

                        <ScrollViewer x:Name="ScrollViewer"
                                VerticalSnapPointsType="Mandatory"
                                VerticalSnapPointsAlignment="Near"
                                VerticalScrollBarVisibility="Hidden"
                                HorizontalScrollMode="Disabled"
                                ZoomMode="Disabled"
                                Template="{StaticResource ScrollViewerScrollBarlessTemplate}" />
                        <RepeatButton x:Name="UpButton" Content="&#xEDDB;" FontFamily="{ThemeResource SymbolThemeFontFamily}" FontSize="8" Height="{ThemeResource LoopingSelectorUpDownButtonHeight}" Padding="0" HorizontalAlignment="Stretch" VerticalAlignment="Top" Visibility="Collapsed" Style="{StaticResource DateTimePickerFlyoutLoopingSelectorNavigationButtonStyle}" Background="{ThemeResource LoopingSelectorUpDownButtonBackground}" Margin="{StaticResource LoopingSelectorUpDownButtonMargin}" IsTabStop="False" />
                        <RepeatButton x:Name="DownButton" Content="&#xEDDC;" FontFamily="{ThemeResource SymbolThemeFontFamily}" FontSize="8" Height="{ThemeResource LoopingSelectorUpDownButtonHeight}" Padding="0" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Visibility="Collapsed" Style="{StaticResource DateTimePickerFlyoutLoopingSelectorNavigationButtonStyle}" Background="{ThemeResource LoopingSelectorUpDownButtonBackground}" Margin="{StaticResource LoopingSelectorUpDownButtonMargin}" IsTabStop="False" />

                    </Grid>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <!-- Default style for Windows.UI.Xaml.Controls.Primitives.LoopingSelectorItem -->
    <Style TargetType="LoopingSelectorItem">
        <Setter Property="HorizontalAlignment" Value="Stretch" />
        <Setter Property="VerticalAlignment" Value="Stretch" />
        <Setter Property="Foreground" Value="{ThemeResource LoopingSelectorItemForeground}" />
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="CornerRadius" Value="{ThemeResource ControlCornerRadius}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="LoopingSelectorItem">
                    <Grid x:Name="Root" Background="Transparent" Margin="{StaticResource LoopingSelectorItemMargin}" CornerRadius="{TemplateBinding CornerRadius}">

                        <VisualStateManager.VisualStateGroups...>

                        <Grid.RenderTransform>
                            <ScaleTransform x:Name="ContentScaleTransform" />
                        </Grid.RenderTransform>
                        <ContentPresenter x:Name="ContentPresenter"
                                Foreground="{TemplateBinding Foreground}"
                                Content="{TemplateBinding Content}"
                                ContentTemplate="{TemplateBinding ContentTemplate}"
                                Padding="2,0,2,0"
                                Margin="2,0,2,0"
                                HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                                AutomationProperties.AccessibilityView="Raw" />

                    </Grid>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</ResourceDictionary>

LoopingSelector本身在CustomDatePickerFlyoutPresenterStyle中(参见引用DayLoopingSelectorprimitives:MonochromaticOverlayPresenter定义,等等),但实际上是在DatePicker代码中示例化的(我没有,也找不到)。
DatePickerFlyout打开时,此XAML生成原始问题中显示的树。

相关问题