惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 同一片海

Win10 资源管理器窗口无边框的问题 Android Studio发布Release版本之坑--Unknown host 'd29vzk4ow07wi7.cloudfront.net' 浏览器外部署Silverlight更新检查失败的原因及对策 C#调用非托管Dll时的参数传递 使用ATL开发ActiveX控件 大数据量传输时配置WCF的注意事项 Silverlight自定义主题 在Silverlight 3中使用主题 [Silverlight]Selector类到底有没有SelectedValue属性? WCF安全之ASP.NET兼容模式 WCF安全之customBinding [Silverlight]一个简单的GroupBox控件 [Silverlight]DataGrid相关的几个小知识点 实现下拉列表支持DataGrid的AutoCompleteBox 可分片数据持久层-ShardingPL使用说明 Silverlight数据绑定中的可空类型与自定义转换器 - 同一片海 一个丑陋的对Silverlight中的Grid无CellPadding的解决方案 - 同一片海 Silverlight中的资源文件 - 同一片海 - 博客园 【分享】SqlServer数据库文档生成工具
[Silverlight]AutoCompleteBox控件的一个Bug?
同一片海 · 2010-04-27 · via 博客园 - 同一片海

我是轻易不说微软的代码有Bug的,因为往往在说了以后发现其实是自己错了。不过这次真的找不出自己哪儿错了,就大胆说一次吧。

先说明一下使用场景,使用Silverlight ToolKit中提供的AutoCompleteBox作为员工输入控件。代码如下:

AutoCompleteBoxDemo.xaml代码:

<UserControl x:Class="AutoCompleteBoxSample.AutoCompleteBoxDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:Controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input" 
    Width="400" Height="300">
    <StackPanel Orientation="Horizontal" Margin="30" VerticalAlignment="Center" >
        <TextBlock VerticalAlignment="Center">Employee:</TextBlock>
        <Controls:AutoCompleteBox  x:Name="acb" Width="160" SelectionChanged="OnSelectionChanged">
            <Controls:AutoCompleteBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Code}"></TextBlock>
                        <TextBlock Text="-"></TextBlock>
                        <TextBlock Text="{Binding Name}"></TextBlock>
                    </StackPanel>                        
                </DataTemplate>
            </Controls:AutoCompleteBox.ItemTemplate>
        </Controls:AutoCompleteBox>
        <TextBlock VerticalAlignment="Center" Margin="10,0,0,0" >You select:</TextBlock>
        <TextBlock Name="txbName" VerticalAlignment="Center"></TextBlock>
    </StackPanel>
</UserControl>

AutoCompleteBoxDemo.xaml.cs代码:

using System.Windows.Controls;

namespace AutoCompleteBoxSample
{
    public partial class AutoCompleteBoxDemo : UserControl
    {
        public AutoCompleteBoxDemo()
        {
            InitializeComponent();

            EmployeeBll bll = new EmployeeBll();
            this.acb.ItemsSource = bll.EmployeeList;
        }

        private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Employee employee = this.acb.SelectedItem as Employee;
            this.txbName.Text = employee == null ? "" : employee.Code;
        }
    }
}

Employee.cs代码:

using System.Collections.Generic;

namespace AutoCompleteBoxSample
{
    public class Employee
    {
        public string Code { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }

    public class EmployeeBll
    {
        public EmployeeBll()
        {
            this.employeeList = new List<Employee>();
            this.employeeList.Add(new Employee { Code = "001", Name = "Mike", Age = 16 });
            this.employeeList.Add(new Employee { Code = "002", Name = "Mike", Age = 18 });
            this.employeeList.Add(new Employee { Code = "003", Name = "Rose", Age = 20 });

        }

        private List<Employee> employeeList;

        public List<Employee> EmployeeList
        {
            get { return this.employeeList; }
        }
    }
}

真是不巧,三个员工中竟然有其中两个重名。

现在我运行程序,开始输入了。输入M后,AutoCompleteBox控件下拉列表中正确的显示出匹配的内容,如下图所示:

image

然后,我用鼠标选择了002-Mike。通过名为txbName的TextBlock展示出来的选择结果却显示我选择了001(如果对选择过程进行跟踪的话,会发现确实首先选中了002,但SelectionChanged事件很快被再次激发,选中项变成了001),如下图所示:

image

通过查看AutoCompleteBox的源码,发现在其中的UpdateTextCompletion方法中用代码片段1重新获取了与文本匹配的选中项,并在重新获取的选中项与当前选中项不一致时改写了当前选中项(见代码片段2)。由于TryGetMatch方法在获取与文本匹配的项时找到第一个匹配项便立即返回,因此当ItemsSource中项的ToString方法的结果不能唯一确定某一个项时(或者为AutoCompleteBox指定ValueMemberPath且ItemsSource中项的该属性值不能唯一确定某一个项时),便会出现以上所描述的问题。

UpdateTextCompletion方法代码片段1:

newSelectedItem = TryGetMatch(text, _view, AutoCompleteSearch.GetFilter(AutoCompleteFilterMode.EqualsCaseSensitive));

UpdateTextCompletion方法代码片段2:

// Update the selected item property

if (SelectedItem != newSelectedItem)
{
    _skipSelectedItemTextUpdate = true;
}
SelectedItem = newSelectedItem;

结束语:或许这种用法不是AutoCompleteBox开发人员的本意?但现实中这种情况还是普遍存在的,不知该不该算是AutoCompleteBox控件的一个Bug。