Получить визуальные эффекты элемента комбинированного блока, если они не помещены в комбинированное окно - PullRequest
0 голосов
/ 05 апреля 2020

В настоящее время я создаю ComboBox меню, которое будет использоваться с TextBox и кнопкой, которая открывает выбор. Пока что меню работает, как и ожидалось, но элементам не хватает визуальных эффектов, которые они имеют при помещении в ComboBox, что означает, например, что я ожидаю, что стиль отображения и фон выбранного элемента изменятся.

Пока что я Попытка использовать шаблон контейнера элемента ComboBox вместо ComboBoxItemRevealStyle для ComboBoxItem, но это не имеет значения. Кроме того, текущее визуальное состояние предмета всегда кажется null, поэтому у меня такое ощущение, что все это нужно делать вручную ...

Мой вопрос: я что-то пропустил или сделал Мне нужно что-то добавить, чтобы сделать эту работу, или мне нужно создать новый контейнерный элемент управления, который управляет всем визуальным материалом, для этой цели?

Следующий код сокращен для краткости.

ComparisoonTextBox.xaml:

<UserControl
    x:Class="Controls.ComparisonTextBox"
    x:Name="ControlRoot"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="32"
    d:DesignWidth="200">

    <Grid>
        <Button x:Name="OperatorButton"
                VerticalAlignment="Stretch"
                HorizontalAlignment="Left"
                Width="40"
                BorderThickness="2,2,0,2"
                Content="{Binding SelectedOperator, ElementName=ControlRoot}" />

        <Popup x:Name="OperatorPopup" IsLightDismissEnabled="True" Margin="0,-7,0,0">
            <Border x:Name="PopupBorder"
                    Background="{ThemeResource ComboBoxDropDownBackground}"
                    BorderThickness="{ThemeResource ComboBoxDropdownBorderThickness}"
                    BorderBrush="{ThemeResource ComboBoxDropDownBorderBrush}"
                    HorizontalAlignment="Stretch"
                    Margin="0,-1,0,-1">
                <ScrollViewer x:Name="ScrollViewer"
                              AutomationProperties.AccessibilityView="Raw"
                              Foreground="{ThemeResource ComboBoxDropDownForeground}"
                              HorizontalScrollBarVisibility="Hidden"
                              HorizontalScrollMode="Disabled"
                              IsDeferredScrollingEnabled="True"
                              IsHorizontalRailEnabled="False"
                              IsVerticalRailEnabled="True"
                              MinWidth="50"
                              VerticalSnapPointsType="OptionalSingle"
                              VerticalScrollMode="Enabled"
                              VerticalScrollBarVisibility="Auto"
                              VerticalSnapPointsAlignment="Near"
                              ZoomMode="Disabled">
                    <ItemsControl x:Name="OperatorItems"
                                  Margin="{ThemeResource ComboBoxDropdownContentMargin}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <ComboBoxItem Style="{ThemeResource ComboBoxItemRevealStyle}"
                                              Tapped="OperatorItemTapped">
                                    <TextBlock Text="{Binding }" />
                                </ComboBoxItem>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                </ScrollViewer>
            </Border>
        </Popup>
    </Grid>
</UserControl>

ComparisonTextBox.xaml.cs:

namespace Controls
{
    using System;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Input;

    /// <summary>
    /// Defines a numeric input control with a button that allows to
    /// select a <see cref="Operator"/> for further comparison operations.
    /// </summary>
    public sealed partial class ComparisonTextBox : UserControl
    {
        private ComboBoxItem selectedItem;

        /// <summary>
        /// Identifies the <see cref="SelectedOperatorProperty"/> dependency property.
        /// </summary>
        public static DependencyProperty SelectedOperatorProperty =
            DependencyProperty.Register(
                nameof(SelectedOperator),
                typeof(Operator),
                typeof(ComparisonTextBox),
                new PropertyMetadata(Operator.Equals));

        /// <summary>
        /// Gets or sets the selected comparison operator to use.
        /// </summary>
        public Operator SelectedOperator
        {
            get => (Operator)GetValue(SelectedOperatorProperty);
            set => SetValue(SelectedOperatorProperty, value);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ComparisonTextBox"/> class.
        /// </summary>
        public ComparisonTextBox()
        {
            InitializeComponent();

            OperatorButton.Click += OperatorButtonClick;

            foreach (var comparisonOperator in Enum.GetValues(typeof(Operator)))
            {
                OperatorItems.Items.Add(comparisonOperator);
            }
        }

        private void OperatorItemTapped(object sender, TappedRoutedEventArgs e)
        {
            var comboBoxItem = (ComboBoxItem)sender;
            comboBoxItem.IsSelected = true;
            SelectedOperator = (Operator)comboBoxItem.DataContext;

            if (!(selectedItem is null))
                selectedItem.IsSelected = false;

            selectedItem = comboBoxItem;
            OperatorPopup.IsOpen = false;
        }

        private void OperatorButtonClick(object sender, RoutedEventArgs e)
        {
            OperatorPopup.IsOpen = true;
        }
    }
}

Operator.cs:

using System.ComponentModel;

/// <summary>
/// Defines comparison operators.
/// </summary>
public enum Operator
{
    [DisplayName(">")]
    Greater,
    [DisplayName(">=")]
    GreaterEqual,
    [DisplayName("=")]
    Equals,
    [DisplayName("<=")]
    LessEqual,
    [DisplayName("<")]
    Less
}

Ответы [ 2 ]

1 голос
/ 06 апреля 2020

но элементам не хватает визуальных эффектов, которые они имеют при помещении в ComboBox, а это означает, что я, например, ожидаю изменения стиля отображения и фона выбранного элемента.

Отличный вопрос, проблема в ItemsControl не содержит стиля раскрытия причины такого поведения. Как правило, ItemsControl используется для визуализации фиксированных элементов. Я предлагаю вам заменить ItemsControl на ListView control.

<ListView x:Name="OperatorItems" Margin="{ThemeResource ComboBoxDropdownContentMargin}">

    <ListView.ItemTemplate>
        <DataTemplate>
            <ComboBoxItem Style="{ThemeResource ComboBoxItemRevealStyle}" Tapped="OperatorItemTapped">
                <TextBlock Text="{Binding}" />
            </ComboBoxItem>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
0 голосов
/ 07 апреля 2020

Как отметил Нико Чжу, я должен был использовать другой контейнер для предметов, чтобы поддерживать стиль раскрытия. Чтобы получить выпадающий список типа ComboBox, к ListViewItem необходимо применить следующий стиль, хотя вы не получите точную копию стиля ComboBoxItem:

<Style TargetType="ListViewItem">
    <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
    <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
    <Setter Property="Background" Value="{ThemeResource ComboBoxItemBackground}"/>
    <Setter Property="Foreground" Value="{ThemeResource ComboBoxItemForeground}"/>
    <Setter Property="BorderBrush" Value="{ThemeResource ComboBoxItemRevealBorderBrush}"/>
    <Setter Property="BorderThickness" Value="{ThemeResource ComboBoxItemRevealBorderThemeThickness}"/>
    <Setter Property="TabNavigation" Value="Local"/>
    <Setter Property="IsHoldingEnabled" Value="True"/>
    <Setter Property="Padding" Value="{ThemeResource ComboBoxItemThemePadding}"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="MinWidth" Value="0"/>
    <Setter Property="MinHeight" Value="0"/>
    <Setter Property="Height" Value="32" />
    <Setter Property="Margin" Value="0" />
    <Setter Property="AllowDrop" Value="False"/>
    <Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/>
    <Setter Property="FocusVisualMargin" Value="0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListViewItem">
                <ListViewItemPresenter x:Name="Root"
                                       CheckBrush="{ThemeResource ListViewItemCheckBrush}"
                                       ContentMargin="{TemplateBinding Padding}"
                                       CheckBoxBrush="{ThemeResource ListViewItemCheckBoxBrush}"
                                       ContentTransitions="{TemplateBinding ContentTransitions}"
                                       CheckMode="{ThemeResource ListViewItemCheckMode}"
                                       DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
                                       DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
                                       DragBackground="{ThemeResource ListViewItemDragBackground}"
                                       DragForeground="{ThemeResource ListViewItemDragForeground}"
                                       FocusBorderBrush="{ThemeResource ListViewItemFocusBorderBrush}"
                                       FocusVisualMargin="{TemplateBinding FocusVisualMargin}"
                                       FocusSecondaryBorderBrush="{ThemeResource ListViewItemFocusSecondaryBorderBrush}"
                                       HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                       Control.IsTemplateFocusTarget="True"
                                       PressedBackground="{ThemeResource ComboBoxItemRevealBackgroundPressed}"
                                       PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackground}"
                                       PointerOverForeground="{ThemeResource ComboBoxItemForegroundPointerOver}"
                                       PointerOverBackground="{ThemeResource ComboBoxItemRevealBackgroundPointerOver}"
                                       RevealBorderThickness="{ThemeResource ComboBoxItemRevealBorderThemeThickness}"
                                       ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
                                       RevealBorderBrush="{ThemeResource ComboBoxItemRevealBorderBrush}"
                                       RevealBackground="{ThemeResource ComboBoxItemRevealBackground}"
                                       SelectedForeground="{ThemeResource ComboBoxItemForegroundSelected}"
                                       SelectionCheckMarkVisualEnabled="{ThemeResource ListViewItemSelectionCheckMarkVisualEnabled}"
                                       SelectedBackground="{ThemeResource ComboBoxItemRevealBackgroundSelected}"
                                       SelectedPressedBackground="{ThemeResource ComboBoxItemRevealBackgroundSelectedPressed}"
                                       SelectedPointerOverBackground="{ThemeResource ComboBoxItemRevealBackgroundSelectedPointerOver}"
                                       VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="Selected"/>
                            <VisualState x:Name="PointerOver">
                                <VisualState.Setters>
                                    <Setter Target="Root.(RevealBrush.State)" Value="PointerOver"/>
                                    <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ComboBoxItemRevealBorderBrushPointerOver}"/>
                                </VisualState.Setters>
                                <Storyboard>
                                    <PointerUpThemeAnimation Storyboard.TargetName="Root"/>
                                </Storyboard>
                            </VisualState>

                            <VisualState x:Name="PointerOverSelected">
                                <VisualState.Setters>
                                    <Setter Target="Root.(RevealBrush.State)" Value="PointerOver"/>
                                    <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ComboBoxItemRevealBorderBrushSelectedPointerOver}"/>
                                </VisualState.Setters>
                            </VisualState>

                            <VisualState x:Name="PointerOverPressed">
                                <VisualState.Setters>
                                    <Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
                                    <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ComboBoxItemRevealBorderBrushSelectedPressed}"/>
                                </VisualState.Setters>
                            </VisualState>

                            <VisualState x:Name="Pressed">
                                <VisualState.Setters>
                                    <Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
                                    <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ComboBoxItemRevealBorderBrushPressed}"/>
                                </VisualState.Setters>
                                <Storyboard>
                                    <PointerDownThemeAnimation Storyboard.TargetName="Root"/>
                                </Storyboard>
                            </VisualState>

                            <VisualState x:Name="PressedSelected">
                                <VisualState.Setters>
                                    <Setter Target="Root.(RevealBrush.State)" Value="Pressed"/>
                                    <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ComboBoxItemRevealBorderBrushPressed}"/>
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>

                        <VisualStateGroup x:Name="DisabledStates">
                            <VisualState x:Name="Enabled"/>

                            <VisualState x:Name="Disabled">
                                <VisualState.Setters>
                                    <Setter Target="Root.RevealBorderThickness" Value="0"/>
                                    <Setter Target="Root.RevealBorderBrush" Value="{ThemeResource ComboBoxItemRevealBorderBrushDisabled}"/>
                                </VisualState.Setters>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                </ListViewItemPresenter>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

И ListView контейнер:

<ListView x:Name="OperatorItems"
          Margin="{ThemeResource ComboBoxDropdownContentMargin}">
    <ListView.ItemContainerTransitions>
        <TransitionCollection />
    </ListView.ItemContainerTransitions>
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding }" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...