Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何创建类似于wpf中evernote的标记控件?

如何创建类似于wpf中evernote的标记控件?
EN

Stack Overflow用户
提问于 2013-03-01 14:16:58
回答 2查看 9.5K关注 0票数 23

我喜欢Evernote (windows版本)中的标签控件,并且想知道是否有类似的东西存在?我只能找到标签云控件。

具体来说,我喜欢在文本框中输入的免费格式,它查找并呈现Intellisense样式--与我键入的标记相匹配。当我选择一个标签时,文本会被一个表示标签的按钮所取代,按钮的文本就是标签文本。

更新:添加屏幕截图

添加一个新标记

查看现有标签并单击“x”删除标记

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-09 10:06:04

这似乎是一个很好的练习,所以我试着构建这个控件。我没有对它进行彻底的测试,如果您想使用它并需要进一步的帮助,请告诉我。

示例用法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns:s="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>

    <Grid>
        <!-- todo: implement ICommand properties on EvernoteTagControl to allow easy binding to the viewmodel. Alternatively, the user could use a behavior to handle TagClick, and if necessary TagAdded/TagRemoved -->
        <local:EvernoteTagControl ItemsSource="{Binding SelectedTags}" TagClick="TagControl_TagClick" >
            <local:EvernoteTagControl.AllTags>
                <s:String>read</s:String>
                <s:String>receipt</s:String>
                <s:String>recipe</s:String>
                <s:String>research</s:String>
                <s:String>restaurants</s:String>
            </local:EvernoteTagControl.AllTags>
        </local:EvernoteTagControl>
    </Grid>
</Window>

ViewModel:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System.Collections.Generic;
using System.ComponentModel;

namespace WpfApplication1
{
    public class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private List<EvernoteTagItem> _selectedTags = new List<EvernoteTagItem>();
        public List<EvernoteTagItem> SelectedTags
        {
            get { return _selectedTags; }
            set
            {
                _selectedTags = value;
                if (_selectedTags != value)
                    OnPropertyChanged("SelectedTags");
            }
        }

        public ViewModel()
        {
            this.SelectedTags = new List<EvernoteTagItem>() { new EvernoteTagItem("news"), new EvernoteTagItem("priority") };
        }

        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

EvernoteTagControl:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace WpfApplication1
{
    [TemplatePart(Name = "PART_CreateTagButton", Type = typeof(Button))]
    public class EvernoteTagControl : ListBox
    {
        public event EventHandler<EvernoteTagEventArgs> TagClick;
        public event EventHandler<EvernoteTagEventArgs> TagAdded;
        public event EventHandler<EvernoteTagEventArgs> TagRemoved;

        static EvernoteTagControl()
        {
            // lookless control, get default style from generic.xaml
            DefaultStyleKeyProperty.OverrideMetadata(typeof(EvernoteTagControl), new FrameworkPropertyMetadata(typeof(EvernoteTagControl)));
        }

        public EvernoteTagControl()
        {
            //// some dummy data, this needs to be provided by user
            //this.ItemsSource = new List<EvernoteTagItem>() { new EvernoteTagItem("receipt"), new EvernoteTagItem("restaurant") };
            //this.AllTags = new List<string>() { "recipe", "red" };
        }

        // AllTags
        public List<string> AllTags { get { return (List<string>)GetValue(AllTagsProperty); } set { SetValue(AllTagsProperty, value); } }
        public static readonly DependencyProperty AllTagsProperty = DependencyProperty.Register("AllTags", typeof(List<string>), typeof(EvernoteTagControl), new PropertyMetadata(new List<string>()));


        // IsEditing, readonly
        public bool IsEditing { get { return (bool)GetValue(IsEditingProperty); } internal set { SetValue(IsEditingPropertyKey, value); } }
        private static readonly DependencyPropertyKey IsEditingPropertyKey = DependencyProperty.RegisterReadOnly("IsEditing", typeof(bool), typeof(EvernoteTagControl), new FrameworkPropertyMetadata(false));
        public static readonly DependencyProperty IsEditingProperty = IsEditingPropertyKey.DependencyProperty;

        public override void OnApplyTemplate()
        {
            Button createBtn = this.GetTemplateChild("PART_CreateTagButton") as Button;
            if (createBtn != null)
                createBtn.Click += createBtn_Click;

            base.OnApplyTemplate();
        }

        /// <summary>
        /// Executed when create new tag button is clicked.
        /// Adds an EvernoteTagItem to the collection and puts it in edit mode.
        /// </summary>
        void createBtn_Click(object sender, RoutedEventArgs e)
        {
            var newItem = new EvernoteTagItem() { IsEditing = true };
            AddTag(newItem);
            this.SelectedItem = newItem;
            this.IsEditing = true;

        }

        /// <summary>
        /// Adds a tag to the collection
        /// </summary>
        internal void AddTag(EvernoteTagItem tag)
        {
            if (this.ItemsSource == null)
                this.ItemsSource = new List<EvernoteTagItem>();

            ((IList)this.ItemsSource).Add(tag); // assume IList for convenience
            this.Items.Refresh();

            if (TagAdded != null)
                TagAdded(this, new EvernoteTagEventArgs(tag));
        }

        /// <summary>
        /// Removes a tag from the collection
        /// </summary>
        internal void RemoveTag(EvernoteTagItem tag, bool cancelEvent = false)
        {
            if (this.ItemsSource != null)
            {
                ((IList)this.ItemsSource).Remove(tag); // assume IList for convenience
                this.Items.Refresh();

                if (TagRemoved != null && !cancelEvent)
                    TagRemoved(this, new EvernoteTagEventArgs(tag));
            }
        }


        /// <summary>
        /// Raises the TagClick event
        /// </summary>
        internal void RaiseTagClick(EvernoteTagItem tag)
        {
            if (this.TagClick != null)
                TagClick(this, new EvernoteTagEventArgs(tag));
        }
    }

    public class EvernoteTagEventArgs : EventArgs
    {
        public EvernoteTagItem Item { get; set; }

        public EvernoteTagEventArgs(EvernoteTagItem item)
        {
            this.Item = item;
        }
    }
}

EvernoteTagItem:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System.Collections;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace WpfApplication1
{
    [TemplatePart(Name = "PART_InputBox", Type = typeof(AutoCompleteBox))]
    [TemplatePart(Name = "PART_DeleteTagButton", Type = typeof(Button))]
    [TemplatePart(Name = "PART_TagButton", Type = typeof(Button))]
    public class EvernoteTagItem : Control
    {

        static EvernoteTagItem()
        {
            // lookless control, get default style from generic.xaml
            DefaultStyleKeyProperty.OverrideMetadata(typeof(EvernoteTagItem), new FrameworkPropertyMetadata(typeof(EvernoteTagItem)));
        }

        public EvernoteTagItem() { }
        public EvernoteTagItem(string text)
            : this()
        {
            this.Text = text;
        }

        // Text
        public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } }
        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(EvernoteTagItem), new PropertyMetadata(null));

        // IsEditing, readonly
        public bool IsEditing { get { return (bool)GetValue(IsEditingProperty); } internal set { SetValue(IsEditingPropertyKey, value); } }
        private static readonly DependencyPropertyKey IsEditingPropertyKey = DependencyProperty.RegisterReadOnly("IsEditing", typeof(bool), typeof(EvernoteTagItem), new FrameworkPropertyMetadata(false));
        public static readonly DependencyProperty IsEditingProperty = IsEditingPropertyKey.DependencyProperty;

        /// <summary>
        /// Wires up delete button click and focus lost 
        /// </summary>
        public override void OnApplyTemplate()
        {
            AutoCompleteBox inputBox = this.GetTemplateChild("PART_InputBox") as AutoCompleteBox;
            if (inputBox != null)
            {
                inputBox.LostFocus += inputBox_LostFocus;
                inputBox.Loaded += inputBox_Loaded;
            }

            Button btn = this.GetTemplateChild("PART_TagButton") as Button;
            if (btn != null)
            {
                btn.Loaded += (s, e) =>
                {
                    Button b = s as Button;
                    var btnDelete = b.Template.FindName("PART_DeleteTagButton", b) as Button; // will only be found once button is loaded
                    if (btnDelete != null)
                    {
                        btnDelete.Click -= btnDelete_Click; // make sure the handler is applied just once
                        btnDelete.Click += btnDelete_Click;
                    }
                };

                btn.Click += (s, e) =>
                {
                    var parent = GetParent();
                    if (parent != null)
                        parent.RaiseTagClick(this); // raise the TagClick event of the EvernoteTagControl
                };
            }

            base.OnApplyTemplate();
        }

        /// <summary>
        /// Handles the click on the delete glyph of the tag button.
        /// Removes the tag from the collection.
        /// </summary>
        void btnDelete_Click(object sender, RoutedEventArgs e)
        {

            var item = FindUpVisualTree<EvernoteTagItem>(sender as FrameworkElement);
            var parent = GetParent();
            if (item != null && parent != null)
                parent.RemoveTag(item);

            e.Handled = true; // bubbling would raise the tag click event
        }

        /// <summary>
        /// When an AutoCompleteBox is created, set the focus to the textbox.
        /// Wire PreviewKeyDown event to handle Escape/Enter keys
        /// </summary>
        /// <remarks>AutoCompleteBox.Focus() is broken: http://stackoverflow.com/questions/3572299/autocompletebox-focus-in-wpf</remarks>
        void inputBox_Loaded(object sender, RoutedEventArgs e)
        {
            AutoCompleteBox acb = sender as AutoCompleteBox;
            if (acb != null)
            {
                var tb = acb.Template.FindName("Text", acb) as TextBox;
                if (tb != null)
                    tb.Focus();

                // PreviewKeyDown, because KeyDown does not bubble up for Enter
                acb.PreviewKeyDown += (s, e1) =>
                {
                    var parent = GetParent();
                    if (parent != null)
                    {
                        switch (e1.Key)
                        {
                            case (Key.Enter):  // accept tag
                                parent.Focus(); 
                                break;
                            case (Key.Escape): // reject tag
                                parent.Focus();
                                parent.RemoveTag(this, true); // do not raise RemoveTag event
                                break;
                        }
                    }
                };
            }
        }

        /// <summary>
        /// Set IsEditing to false when the AutoCompleteBox loses keyboard focus.
        /// This will change the template, displaying the tag as a button.
        /// </summary>
        void inputBox_LostFocus(object sender, RoutedEventArgs e)
        {
            this.IsEditing = false;
            var parent = GetParent();
            if (parent != null)
                parent.IsEditing = false;
        }

        private EvernoteTagControl GetParent()
        {
            return FindUpVisualTree<EvernoteTagControl>(this);
        }

        /// <summary>
        /// Walks up the visual tree to find object of type T, starting from initial object
        /// http://www.codeproject.com/Tips/75816/Walk-up-the-Visual-Tree
        /// </summary>
        private static T FindUpVisualTree<T>(DependencyObject initial) where T : DependencyObject
        {
            DependencyObject current = initial;
            while (current != null && current.GetType() != typeof(T))
            {
                current = VisualTreeHelper.GetParent(current);
            }
            return current as T;
        }
    }
}

主题/Generic.xaml:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                            xmlns:local="clr-namespace:WpfApplication1"
                            xmlns:tkInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit">

    <SolidColorBrush x:Key="HighlightBrush" Color="DodgerBlue" />

    <!-- EvernoteTagControl default style -->
    <Style TargetType="{x:Type local:EvernoteTagControl}">
        <Style.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="White"/>
            <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="White" />
            <LinearGradientBrush x:Key="IconBrush" EndPoint="0,1">
                <GradientStop Color="#5890f0" Offset="0" />
                <GradientStop Color="#0351d7" Offset="1" />
            </LinearGradientBrush>
        </Style.Resources>
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
        <Setter Property="VerticalAlignment" Value="Top" />
        <Setter Property="Margin" Value="5" />
        <Setter Property="MinHeight" Value="25" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:EvernoteTagControl}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Path Grid.Column="0" Margin="2" Fill="{StaticResource IconBrush}" Height="19" Stretch="Uniform" Data="M 50.535714,0.44196425 0.00446427,34.754464 l 0,106.906246 100.71874573,0 0,-107.124996 L 50.535714,0.44196425 z m 0.1875,21.21874975 c 6.311826,0 11.40625,5.094424 11.40625,11.40625 0,6.311826 -5.094424,11.4375 -11.40625,11.4375 -6.311826,0 -11.4375,-5.125674 -11.4375,-11.4375 0,-6.311826 5.125674,-11.40625 11.4375,-11.40625 z" />
                        <ItemsPresenter Grid.Column="1"  />
                        <Button Margin="5,0,0,0" Grid.Column="2" Content="Click to add tag..." x:Name="PART_CreateTagButton">
                            <Button.Template>
                                <ControlTemplate TargetType="Button">
                                    <ContentPresenter TextElement.Foreground="#FF555555" VerticalAlignment="Center" />
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsMouseOver" Value="True">
                                            <Setter Property="Cursor" Value="Hand" />
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                                </ControlTemplate>
                            </Button.Template>
                        </Button>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEditing" Value="True">
                            <Setter TargetName="PART_CreateTagButton" Property="Visibility" Value="Collapsed" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemContainerStyle">
            <Setter.Value>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="FocusVisualStyle" Value="{x:Null}" />
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemsPanel" >
            <Setter.Value>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <!-- EvernoteTagItem default style -->
    <Style TargetType="{x:Type local:EvernoteTagItem}">
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
        <Setter Property="MinWidth" Value="50" />
        <Setter Property="Margin" Value="0,0,2,0" />
        <Setter Property="Padding" Value="5,2,0,2" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:EvernoteTagItem}">
                    <Button x:Name="PART_TagButton" Content="{TemplateBinding Text}" Margin="{TemplateBinding Margin}" Padding="{TemplateBinding Padding}">
                        <Button.Template>
                            <ControlTemplate TargetType="Button">
                                <Border Margin="{TemplateBinding Margin}" Padding="{TemplateBinding Padding}" BorderBrush="Gray" BorderThickness="1" CornerRadius="2" Background="#01FFFFFF">
                                    <Grid >
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="*" />
                                            <ColumnDefinition Width="Auto" />
                                        </Grid.ColumnDefinitions>
                                        <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,0,2" />
                                        <Button x:Name="PART_DeleteTagButton" Grid.Column="1"  Margin="3,0" VerticalAlignment="Center" HorizontalAlignment="Right" Visibility="Hidden"  >
                                            <Button.Template>
                                                <ControlTemplate>
                                                    <Grid Height="10" Width="10" Background="#01FFFFFF" >
                                                        <Path Stretch="Uniform" ClipToBounds="True" Stroke="{StaticResource HighlightBrush}" StrokeThickness="2" Data="M 85.364473,6.9977109 6.0640998,86.29808 6.5333398,85.76586 M 6.9926698,7.4977169 86.293043,86.79809 85.760823,86.32885"  />
                                                    </Grid>
                                                </ControlTemplate>
                                            </Button.Template>
                                        </Button>
                                    </Grid>
                                </Border>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter Property="Foreground" Value="{StaticResource HighlightBrush}" />
                                        <Setter TargetName="PART_DeleteTagButton" Property="Visibility" Value="Visible" />
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Button.Template>
                    </Button>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsEditing" Value="True">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:EvernoteTagItem}">
                            <tkInput:AutoCompleteBox x:Name="PART_InputBox"
                                                             Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" 
                                                             ItemsSource="{Binding AllTags, RelativeSource={RelativeSource AncestorType={x:Type local:EvernoteTagControl}}}"
                                                             IsTextCompletionEnabled="True"
                                                             />
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

</ResourceDictionary>
票数 44
EN

Stack Overflow用户

发布于 2013-03-06 10:58:54

下面是我如何创建这个控件的方法。

高级别概览:

该控件将包含以下主要组件:(1) AutoCompleteTextBoxAutoCompleteComboBox (2)您描述的“按钮”控件(3)用于保存应用标记的UI集合。AutoCompleteTextBox和保存应用标记的集合将提前定位在您选择的布局容器中。

首先,我们可以利用AutoCompleteTextBoxAutoCompleteComboBox作为用户类型提供Intellisense样式的选项。接下来,我们“监听”用户从下拉列表中选择一个呈现的标签,并动态地创建一个新的“按钮”控件(我们可以提前为它创建一个UserControl/CustomControl,但是我们至少需要“新”一个)。“按钮”将包含AutoCompleteTextBox的文本作为其文本。最后,我们将新的“按钮”插入到一个ListBox (或其他相关的UI集合类型)中,它保存了所有当前应用的标记。

详细信息:

有一些AutoCompleteTextBox控件,但是我将描述如何使用this CodeProject one。这个示例项目展示了如何使用常规TextBoxAutoCompleteComboBoxAutoCompleteTextBox来实现intellisense样式的选项。这个项目的核心部分实际上是AutoCompleteManager和一个IAutoCompleteDataProvider类型的DataProvider,以及IAutoAppendDataProvider

在描述更多细节之前,这里有一些AutoCompleteTextBox控件的屏幕截图(请注意,我对ListBoxItems使用的样式与原始作者提供的不同)。该控件的AutoAppend属性是一个很好的触摸(这个示例打开它,所以在我开始键入当前匹配时,我会自动“完成”我的话)。在输入“i”之后:

在“印第安纳”上空盘旋我的鼠标后:

点击“印第安纳”后:

由于这个项目的代码为我们处理下拉选项,我们现在需要“监听”当用户从下拉列表中选择一个项目并相应地创建新的“按钮”控件。有两个主要案例----我们需要处理这个问题。

第一种情况是当用户用鼠标从列表中选择一项时。为了处理这个问题,我们可以插入代码,以便在MouseLeftButtonUp处理程序中的AutoCompleteManager.cs中创建新的“按钮”控件,该控件位于第451行附近:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    private void ListBox_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        ListBoxItem item = null;
        var d = e.OriginalSource as DependencyObject;
        while (d != null)
        {
            if (d is ListBoxItem)
            {
                item = d as ListBoxItem;
                break;
            }
            d = VisualTreeHelper.GetParent(d);
        }
        if (item != null)
        {
            _popup.IsOpen = false;
            UpdateText(item.Content as string, true);

            // User has selected an item with the mouse... 
            //  ** Add your new code HERE... something like:
            // 
            // TagButton tagButton = new TagButton(_textBox.Text); // _textBox is the TextBox to which the AutoCompleteManager has been applied
            // _autoCompleteTagControl.TagContainer.Add(tagButton); // _autoCompleteTagControl would be the control that we're making... it contains out other controls - I'm assuming we've passed it in or made it available.
        }
    }

第二种情况下,是当用户按下enter键从列表中选择一项时。为了处理这个问题,我们可以在TextBox_PreviewKeyDown处理程序中插入类似的新代码,在AutoCompleteManager.cs中,在第291行前后:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        _supressAutoAppend = e.Key == Key.Delete || e.Key == Key.Back;
        if (!_popup.IsOpen)
        {
            return;
        }
        if (e.Key == Key.Enter)
        {
            _popup.IsOpen = false;
            _textBox.SelectAll();

            // User has selected an item by hitting the enter key...
            //  ** Add your new code HERE to create new TagButton, etc.
        }
        // ...
     }

细印细节

如果您决定使用我提到的AutoCompleteTextBox中的CodeProject,您可能需要应用一些修复。在将所有内容导入更大的项目后,我遇到了两个小问题(它们在运行包含的示例项目时没有发生)。第一个是绑定错误:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=HorizontalContentAlignment; DataItem=null; target element is 'ListBoxItem' (Name=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')

其他人也曾在ListBoxes上遇到过这个问题,描述了here。正如这篇文章的答案之一所暗示的那样,我能够在我的风格中为HorizontalContentAligment和VerticalContentAlignment提供一个显式的样式设置来解决这个问题。

第二个问题发生在AutoCompleteTextBox出现在包含选项卡的应用程序中之后。当您在TabControl中有控件时,嵌套控件将经常引发它们加载的事件--每次单击包含该控件的选项卡时至少会引发一次。这导致对AutoCompleteManager's AttachTextBox()方法的意外额外调用,导致debug.Assert()失败并出现异常(原始作者假设加载的事件只引发一次)。到目前为止,我需要处理的唯一修复方法是在AutoCompeteTextBox.cs中。我只是添加了一个_isInitialized标志,以确保AttachTextBox只被调用一次:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    void AutoCompleteTextBox_Loaded(object sender, RoutedEventArgs e)
    {
        if (! _isInitialized)
        {
            _acm.AttachTextBox(this);
            _isInitialized = true;
        }
    }

使用这种方法应该允许您创建一个行为类似于您描述的控件。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15167809

复制
相关文章
【jquery基础】按钮禁用和启用
在html标签中设置按钮被禁用,可以使用如下代码 <input type='button' id='test' value='disabled'> 在jquery中可以使用attr()函数修改按钮的disable属性 $(“#test”).attr(‘disabled',false); jquery 控制button的disabled属性
用户5640963
2019/07/25
4.6K0
Jquery禁用/启用按钮与文本框代码
在jquery中如果要禁止文框与按钮恢复效果我们需要动态设置disabled即可了,如果要设置为只读我们只要设置readonly即可。
botkenni
2022/01/10
2.3K0
IQKeyboardManager 启用/禁用
1.在摸个界面完全禁用IQKeyboard - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; //TODO: 页面appear 禁用 [[IQKeyboardManager sharedManager] setEnable:NO]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:anim
developerbfl
2018/06/05
2.5K0
Vbs 禁用启用网卡
在实际工作中,经常碰到需要通过脚本启用禁用网卡的情况,在网上找了一个脚本,实际是通过模拟键盘操作来启用禁用,但对于多种系统和比较复杂的情况操作性不好。
力哥聊运维与云计算
2019/06/28
2K0
Spring boot with Schedule (启用/禁用)
本文节选自《Netkiller Java 手札》 5.19.4. 计划任务控制 matchIfMissing = true, 如果改属性条目不存在返回 true @ConditionalOnProperty("batch.metrics.export.influxdb.enabled") # mybean.enabled = true @ConditionalOnProperty(value='mybean.enabled') @ConditionalOnProperty(value = "endp
netkiller old
2018/03/05
2.8K0
jQuery 获取对象 根据属性、内容匹配, 还有表单元素匹配
指定元素中包含 id 属性的, 如: $("span[id]")  代码如下: <span id="span1" name="S1">AAA</span><br/>  <span id="span2" name="S2">BBB</span><br/>  <span name="Sx3">CCC</span><br/>  <span name="Sx4">DDD</span><br/>  <div id="div1" name="Dx1">EEE</div>  <div name="D2">FFF</div
hbbliyong
2018/03/06
1.6K0
jquery 表单验证
("form :input.required").each(function(){
用户5760343
2019/10/10
3.6K0
jquery 表单验证
jquery 表单事件
.blur()    当元素失去焦点的时候触发事件。   .blur(handler(eventObject))     handler(eventObject)       每当事件触发时候执行的函数。   .blur([eventData],handler(eventObject))     eventData       一个对象,它包含的数据键值对映射将被传递给事件处理程序。     handler(eventObject)       每当事件
用户1197315
2018/01/19
1.5K0
Linux 中如何启用和禁用网卡?
当你添加一个网卡或者从一个物理网卡创建出一个虚拟网卡的时候,你可能需要使用这些命令将新网卡启用起来。另外,如果你对网卡做了某些修改或者网卡本身没有启用,那么你也需要使用以下的某个命令将网卡启用起来。
用户4988085
2021/09/14
18.6K0
jquery根据属性选择
有信仰的人不会孤独。——阿列克谢耶维奇 分享一个jquery选择器的小技巧 我们可以通过自定义属性键值选中一个元素 例如如下元素: <div ruben="vampire">阿超</div> 然后我们通过ruben=vampire选中这个div 就可以如下写法: let vampire = $('div[ruben="vampire"]') 我们可以简单测试一下输出里面的内容 <div ruben="vampire">阿超</div> <script type="text/javascript">
阿超
2022/08/17
1.9K0
jquery根据属性选择
JQuery表格表单操作
1、多选框应用代码示例 <form action=”#” method=”post”> 你喜欢的明星是?<br /> <input type=”checkbox” name=”boxs” value=”张嘉译” id=”1″ /><label for=”1″>张嘉译</label> <input type=”checkbox” name=”boxs” value=”周润发” id=”2″ /><label for=”2″>周润发</label> <input type=”checkbox” name=”bo
苦咖啡
2018/05/07
1.5K0
bootstrapValidator 中文API
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
颍川
2019/11/21
13.2K1
jquery 操作表单表格
$("tr:contains('王五')").addClass("selected")
用户5760343
2019/10/08
1.5K0
jquery 操作表单表格
Jquery 异步提交表单
前台部分代码: <div id='error'></div><!--错误提示信息--> <input type='text' id='username' name='username' readonly='Readonly'/><!--readonly为只读--> <input type='password' id='password' name='password'> <input type='text' id='company' name='company'> <input type='text'
用户1503405
2021/09/23
3K0
JQuery 学习—JQuery Validation表单验证范例[通俗易懂]
jQuery Validato表单验证插件,它是基于jQuery类库,实现了js脚本于页面html代码的分离。你可以划分多个校验组,每个组的校验都是互不影响。对一个表单对象,你只需要写一行代码就可以轻松实现无数种(理论上)脚本控制。
全栈程序员站长
2022/07/19
1.8K0
Element 根据描述展示表单
假如数据格式如下: formData: [ { title: "气密性测试", param: [ { mode: "检查方式1", way: "单选", required: "Y", content: ["检漏仪", "u形管"], value: "检漏仪"
一只图雀
2020/09/21
9190
Oracle 启用被禁用的外键
在Oracle中,面对已经被禁用的外键,我们该如何将它重新启用呢?本教程就为大家带来Oracle外键启用方法。
用户8965210
2021/09/02
8280
PHP过滤表单字段
从post来的进行addslashes后就可存入数据库了,取出后直接echo即可 普通的文本: 1.htmlspecialchars接着addslashes存入数据库,取出后直接echo即可。 2.addslashes存入数据库,取出后htmlspecialchars输出。 说明: addslashes仅仅是为了让原来的字符正确地进入数据库。 htmlspecialchars是吧html标签转化掉。
黄啊码
2020/05/29
3.1K0
用jquery实现表单验证_jquery验证插件
功能强大的 jQuery 表单验证插件,适用于日常的 E-mail、电话号码、网址等验证及 Ajax 验证,除自身拥有丰富的验证规则外,还可以添加自定义的验证规则。
全栈程序员站长
2022/11/09
4.3K0
点击加载更多

相似问题

jQuery Ajax文件上传formData

12

基于Laravel后端的资源+ FormData文件上传

10

用jquery和FormData上传文件

12

jquery文件上传formData输入名称

13

在Express中访问文件上传formData

13
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文