简体   繁体   English

在WinRT中等效的可编辑ComboBox?

[英]Equivalent of editable ComboBox in WinRT?

The standard (desktop) windows combobox has three styles; 标准(桌面)windows组合框有三种风格; Simple, Dropdown, and Drop List. 简单,下拉列表和删除列表。 Dropdown works like an edit control and a combobox, whereas Drop List doesn't allow editing. Dropdown的工作方式类似于编辑控件和组合框,而Drop List不允许编辑。

Am I missing something, or does the XAML ComboBox control in a Windows 8 store app only support the Drop List style? 我错过了什么,或者Windows 8商店应用程序中的XAML ComboBox控件是否仅支持Drop List样式?

I was halfway through implementing something when I ran into this, and the more I look, the more it seems that it just isn't supported. 当我遇到这个问题时,我已经实现了一些东西,我看的越多,它就越不被支持。

Do I really need to replace the ComboBoxes in my screens with an edit control followed by a listbox? 我是否真的需要使用编辑控件和列表框替换屏幕中的ComboBox?

Yuck. 呸。

thanks to edward.ho.tpe's answer I wrote myself a little EditableComboBox by using an TextBox inside a ComboBoxItem . 感谢edward.ho.tpe的回答,我通过在ComboBoxItem使用TextBox给自己写了一个小EditableComboBox。 If you want to use it multiple times it might be better to create a UserControl. 如果要多次使用它,最好创建一个UserControl。

However this is how I did it: 不过这就是我做到的:

The style: 样式:

<SolidColorBrush x:Key="TransparentBrush" Color="Transparent"/>
<Style x:Key="ComboBoxItemTextBox" TargetType="TextBox">
    <Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}"/>
    <Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}"/>
    <Setter Property="Foreground" Value="{ThemeResource TextBoxForegroundThemeBrush}"/>
    <Setter Property="Background" Value="{StaticResource TransparentBrush}"/>
    <Setter Property="BorderBrush" Value="{StaticResource TransparentBrush}"/>
    <Setter Property="SelectionHighlightColor" Value="{ThemeResource TextSelectionHighlightColorThemeBrush}"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
    <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden"/>
    <Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False"/>
    <Setter Property="Padding" Value="{ThemeResource TextControlThemePadding}"/>
    <Setter Property="Margin" Value="-10,0,0,0"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TextBox">
                <Grid>
                    <Grid.Resources>
                        <Style x:Name="DeleteButtonStyle" TargetType="Button">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="Button">
                                        <Grid>
                                            <VisualStateManager.VisualStateGroups>
                                                <VisualStateGroup x:Name="CommonStates">
                                                    <VisualState x:Name="Normal"/>
                                                    <VisualState x:Name="PointerOver">
                                                        <Storyboard>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxButtonPointerOverBackgroundThemeBrush}"/>
                                                            </ObjectAnimationUsingKeyFrames>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxButtonPointerOverBorderThemeBrush}"/>
                                                            </ObjectAnimationUsingKeyFrames>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="GlyphElement">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxButtonPointerOverForegroundThemeBrush}"/>
                                                            </ObjectAnimationUsingKeyFrames>
                                                        </Storyboard>
                                                    </VisualState>
                                                    <VisualState x:Name="Pressed">
                                                        <Storyboard>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxButtonPressedBackgroundThemeBrush}"/>
                                                            </ObjectAnimationUsingKeyFrames>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxButtonPressedBorderThemeBrush}"/>
                                                            </ObjectAnimationUsingKeyFrames>
                                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="GlyphElement">
                                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxButtonPressedForegroundThemeBrush}"/>
                                                            </ObjectAnimationUsingKeyFrames>
                                                        </Storyboard>
                                                    </VisualState>
                                                    <VisualState x:Name="Disabled">
                                                        <Storyboard>
                                                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement"/>
                                                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BorderElement"/>
                                                        </Storyboard>
                                                    </VisualState>
                                                </VisualStateGroup>
                                            </VisualStateManager.VisualStateGroups>
                                            <Border x:Name="BorderElement" BorderBrush="{ThemeResource TextBoxButtonBorderThemeBrush}" BorderThickness="{TemplateBinding BorderThickness}"/>
                                            <Border x:Name="BackgroundElement" Background="{ThemeResource TextBoxButtonBackgroundThemeBrush}" Margin="{TemplateBinding BorderThickness}">
                                                <TextBlock x:Name="GlyphElement" AutomationProperties.AccessibilityView="Raw" Foreground="{ThemeResource TextBoxButtonForegroundThemeBrush}" FontStyle="Normal" FontFamily="{ThemeResource SymbolThemeFontFamily}" HorizontalAlignment="Center" Text="&#xE0A4;" VerticalAlignment="Center"/>
                                            </Border>
                                        </Grid>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </Grid.Resources>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxDisabledBackgroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="BorderElement">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxDisabledBorderThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxDisabledForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextContentPresenter">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxDisabledForegroundThemeBrush}"/>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Normal">
                                <Storyboard>
                                    <DoubleAnimation Duration="0" To="{ThemeResource TextControlBackgroundThemeOpacity}" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement"/>
                                    <DoubleAnimation Duration="0" To="{ThemeResource TextControlBorderThemeOpacity}" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BorderElement"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="PointerOver">
                                <Storyboard>
                                    <DoubleAnimation Duration="0" To="{ThemeResource TextControlPointerOverBackgroundThemeOpacity}" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement"/>
                                    <DoubleAnimation Duration="0" To="{ThemeResource TextControlPointerOverBorderThemeOpacity}" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BorderElement"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Focused"/>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="ButtonStates">
                            <VisualState x:Name="ButtonVisible"/>
                            <VisualState x:Name="ButtonCollapsed"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border x:Name="BackgroundElement" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" Margin="{TemplateBinding BorderThickness}" Grid.Row="1" Grid.RowSpan="1"/>
                    <Border x:Name="BorderElement" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="2" Grid.Row="1" Grid.RowSpan="1"/>
                    <ContentPresenter x:Name="HeaderContentPresenter" Grid.ColumnSpan="2" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Foreground="{ThemeResource TextBoxForegroundHeaderThemeBrush}" FontWeight="Semilight" Margin="0,4,0,4" Grid.Row="0"/>
                    <ScrollViewer x:Name="ContentElement" AutomationProperties.AccessibilityView="Raw" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsTabStop="False" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="Disabled"/>
                    <ContentControl x:Name="PlaceholderTextContentPresenter" Grid.ColumnSpan="2" Content="{TemplateBinding PlaceholderText}" Foreground="{ThemeResource TextBoxPlaceholderTextThemeBrush}" IsHitTestVisible="False" IsTabStop="False" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1"/>
                    <Button x:Name="DeleteButton" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="1" FontSize="{TemplateBinding FontSize}" IsTabStop="False" Grid.Row="1" Style="{StaticResource DeleteButtonStyle}" Visibility="Collapsed" VerticalAlignment="Stretch"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The ComboBox: ComboBox:

<ComboBox SelectionChanged="ComboBox_SelectionChanged">
    <ComboBoxItem IsSelected="True">
        <TextBox x:Name="tbComboBox" Style="{StaticResource ComboBoxItemTextBox}" KeyDown="tbComboBox_KeyDown"/>
    </ComboBoxItem>
    <ComboBoxItem>Item 1</ComboBoxItem>
    <ComboBoxItem>Item 2</ComboBoxItem>
    <ComboBoxItem>Item 3</ComboBoxItem>
    <ComboBoxItem>Item 4</ComboBoxItem>
</ComboBox>

The event handlers: 事件处理程序:

private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.AddedItems.Count == 1 && e.AddedItems[0] != (sender as ComboBox).Items[0])
    {
        (sender as ComboBox).SelectedIndex = 0;
        tbComboBox.Text = (e.AddedItems[0] as ComboBoxItem).Content as String;
    }
}

private void tbComboBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
    if (e.Key == Windows.System.VirtualKey.Space)
    {
        if (tbComboBox.SelectionLength > 0)
        {
            tbComboBox.Text = tbComboBox.Text.Remove(tbComboBox.SelectionStart, tbComboBox.SelectionLength);
            tbComboBox.SelectionLength = 0;
        }
        int pos = tbComboBox.SelectionStart;
        tbComboBox.Text = tbComboBox.Text.Insert(pos, " ");
        tbComboBox.SelectionStart = pos + 1;
        e.Handled = true;
    }
}

So basically what this is: 基本上这是什么:

As edward.ho.tpe suggested a TextBox as the content of the first item of a ComboBox . 正如edward.ho.tpe建议将TextBox作为ComboBox第一项的内容。 The TextBox has a custom style that removes the background, the border, moves it a little to the left (optional - but i like it since it provides more space to write), and changes the delete button to stay collapsed. TextBox有一个自定义样式,删除背景,边框,向左移动一点(可选 - 但我喜欢它,因为它提供了更多的空间来写),并更改删除按钮以保持折叠状态。 The SelectionChanged event handler makes sure that the TextBox stays the SelectedItem and only changes the Text based on the content of the selected item and the KeyDown event handler handles the space keydown because otherwise that would trigger the Dropdown of the ComboBox . SelectionChanged事件处理程序确保TextBox保持SelectedItem并且仅基于所选项的内容更改Text ,并且KeyDown事件处理程序处理空间keydown,否则将触发ComboBox的Dropdown。

Syncfusion Controls for WinRT includes a ComboBox too. WinRT的Syncfusion控件也包含一个ComboBox。 But it is not free. 但它不是免费的。

Since combobox item in WinRT can be anything, you can : 由于WinRT中的组合框项目可以是任何内容,您可以:

<ComboBoxItem>
<TextBox Text="something"/>
</ComboBoxItem>

When user clicks that item, he/she can edit its content. 当用户点击该项目时,他/她可以编辑其内容。

It's up to you whether to have the edit result change that item's editbox or just adding a new combobox item to that combobox. 是否让编辑结果更改该项目的编辑框或只是将新的组合框项目添加到该组合框中取决于您。 Process this in the LostFocus event. 在LostFocus事件中处理此事。

You are not missing anything. 你没有遗漏任何东西。 There is no editable combobox in the out-of-the-box toolbox. 开箱即用的工具箱中没有可编辑的组合框。

You might have tried the winrt xaml toolkit @ http://winrtxamltoolkit.codeplex.com/ But that does not have one either. 您可能已经尝试过winrt xaml工具包@ http://winrtxamltoolkit.codeplex.com/但是也没有。 Too bad because it is free. 太糟糕了,因为它是免费的。

You might have looked at ComponentOne @ http://www.componentone.com/SuperProducts/StudioWinRTXAML/ But that does not have one either. 你可能已经看过ComponentOne @ http://www.componentone.com/SuperProducts/StudioWinRTXAML/但是也没有。

You might have looked at Infragistics @ http://www.infragistics.com/products/technology-previews/windows8/ But that toolkit is in "preview" still. 您可能已经查看了Infragistics @ http://www.infragistics.com/products/technology-previews/windows8/但该工具包仍在“预览”中。

You might have looked at Telerik @ http://www.telerik.com/products/windows-8/overview.aspx They have a combobox http://www.telerik.com/products/windows-8/controls/combo-box.aspx 你可能已经看过Telerik @ http://www.telerik.com/products/windows-8/overview.aspx他们有一个组合框http://www.telerik.com/products/windows-8/controls/combo- box.aspx

But you might want something free. 但你可能想要一些免费的东西。 There is no Microsoft XAML Toolkit at this time. 目前没有Microsoft XAML Toolkit。 So you need to build your own or find an open source project. 因此,您需要构建自己的或找到一个开源项目。 I could not find such a project at this time. 我此时找不到这样的项目。

But what is an editable combobox really? 但是什么是可编辑的组合框呢? A standard combobox and a textbox, right? 一个标准的组合框和一个文本框,对吗?

By setting 通过设置

combobox.ComboBoxMode = ComboBoxModes.Editable 

in syncfusion SfComboBox, you can edit the combobox. 在syncfusion SfComboBox中,您可以编辑组合框。

Regards, 问候,

Elavarasan M Elavarasan M.

AutoSuggestBox UI控件

Try The UIControl called AutoSuggestBox 试试名为AutoSuggestBox的UIControl

<AutoSuggestBox PlaceholderText="Company">
     <AutoSuggestBox.QueryIcon>
         <SymbolIcon Symbol="find"/>
     </AutoSuggestBox.QueryIcon>
</AutoSuggestBox>

我知道这是一个古老的问题,但对于像我这样的新搜索者我找到了属性ComboBox.IsEditable很好

I have searched everywhere for a Searchable Combobox and have resolved to writing my own. 我到处搜索了一个可搜索的组合框,并决定自己编写。 It is not quite like your editable combobox, but will filter the options in a combobox when typing. 它不像您的可编辑组合框,但会在键入时过滤组合框中的选项。 Maybe this could help someone. 也许这可以帮助某人。

You would define a new control like this: 您可以像这样定义一个新控件:

<control:SearchableComboBox Margin='5'
          x:Name='ComboBoxCountry'
          ItemsSourceList='{Binding CountryList}'
          ItemsSourceListBase='{Binding CountryListBase}'
          PlaceholderText='Select Country'/>

Unfortunately you still need to provide a duplicate list, CountryListBase. 不幸的是,您仍然需要提供重复列表CountryListBase。 If you have suggestions on improving this, let me know! 如果您有改进建议,请告诉我!

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;

namespace eMoyoConnect.Controls
{
    public class SearchableComboBox : ComboBox
    {

        public ObservableCollection<string> ItemsSourceList
        {
            get { return (ObservableCollection<string>)GetValue(ItemsSourceListProperty); }
            set
            {
                SetValue(ItemsSourceListProperty, value);
                this.ItemsSource = ItemsSourceList;
            }
        }

        public static readonly DependencyProperty ItemsSourceListProperty =
            DependencyProperty.Register("ItemsSourceList", typeof(ObservableCollection<string>), typeof(SearchableComboBox),
            new PropertyMetadata(null, ItemsSourceListChanged));

        private static void ItemsSourceListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var plv = d as SearchableComboBox;
            plv.ItemsSource = e.NewValue;
        }

        public Collection<string> ItemsSourceListBase
        {
            get { return (Collection<string>)GetValue(ItemsSourceListBaseProperty); }
            set
            {
                SetValue(ItemsSourceListBaseProperty, value);
                this.ItemsSource = ItemsSourceListBase;
            }
        }

        public static readonly DependencyProperty ItemsSourceListBaseProperty =
            DependencyProperty.Register("ItemsSourceListBase", typeof(Collection<string>), typeof(SearchableComboBox),
            new PropertyMetadata(null, ItemsSourceListBaseChanged));

        private static void ItemsSourceListBaseChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var plv = d as SearchableComboBox;
            plv.ItemsSource = e.NewValue;
        }

        string FilterString = "";
        protected override void OnKeyDown(KeyRoutedEventArgs e)
        {
            if (IsLetterOrSpace(e.Key))
            {
                if (e.Key == VirtualKey.Space)
                    FilterString += " ";
                else
                    FilterString += e.Key.ToString();
                FilterList(FilterString);
                this.ItemsSource = ItemsSourceList;
                if (ItemsSourceList.Count > 0)
                    this.SelectedIndex = 0;
            }
            else if (e.Key == VirtualKey.Back)
            {
                if (FilterString.Length > 0)
                {
                    FilterString = FilterString.Substring(0, FilterString.Length - 1);
                    FilterList(FilterString);
                    this.ItemsSource = ItemsSourceList;
                    if (ItemsSourceList.Count > 0)
                        this.SelectedIndex = 0;
                }
            }

            if (e.Key != VirtualKey.Space)
            {
                base.OnKeyDown(e);
            }
        }

        protected override void OnGotFocus(RoutedEventArgs e)
        {
            string selectedValue = "";
            if (this.SelectedValue != null)
                selectedValue = (string)this.SelectedValue;
            FilterString = "";
            FilterList(FilterString);
            if (!string.IsNullOrEmpty(selectedValue))
                this.SelectedValue = selectedValue;
        }

        internal void FilterList(string FilterString)
        {
            ItemsSourceList.Clear();
            IEnumerable<string> list;
            if (!string.IsNullOrEmpty(FilterString))
                list = ItemsSourceListBase.Where(x => x.StartsWith(FilterString));
            else
                list = ItemsSourceListBase;
            foreach (var item in list)
                ItemsSourceList.Add(item);
        }

        private bool IsLetterOrSpace(VirtualKey key)
        {
            return (key == VirtualKey.A
                || key == VirtualKey.B
                || key == VirtualKey.C
                || key == VirtualKey.D
                || key == VirtualKey.E
                || key == VirtualKey.F
                || key == VirtualKey.G
                || key == VirtualKey.H
                || key == VirtualKey.I
                || key == VirtualKey.J
                || key == VirtualKey.K
                || key == VirtualKey.L
                || key == VirtualKey.M
                || key == VirtualKey.N
                || key == VirtualKey.O
                || key == VirtualKey.P
                || key == VirtualKey.Q
                || key == VirtualKey.R
                || key == VirtualKey.S
                || key == VirtualKey.T
                || key == VirtualKey.U
                || key == VirtualKey.V
                || key == VirtualKey.W
                || key == VirtualKey.X
                || key == VirtualKey.Y
                || key == VirtualKey.Z
                || key == VirtualKey.Space);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM