枚举与Combox的SelectedIndex绑定出现怪异问题的解决方案

原创 2013年12月04日 09:59:29

在Combox中有一系列的选项,其选项的SelectedIndex值对应了相应的枚举值,而这些枚举值会影响着后续的工作模式,所以就想着将Combox的SelectedIndex和枚举值进行双向绑定,代码如下

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

//Add
using System.Linq.Expressions;

namespace ComboxBinding
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }

        private BindingDataProperyty _bindingDataProperty = null;

        private void FormMain_Load(object sender, EventArgs e)
        {
            for (int index = 0; index < 10; index++)
            {
                comboBoxData.Items.Add(index.ToString());
            }
            
            _bindingDataProperty = new BindingDataProperyty();
            comboBoxData.DataBindings.Add("SelectedIndex",
                                        _bindingDataProperty,
                                        "Way_pro",
                                        false,
                                        DataSourceUpdateMode.OnPropertyChanged);
        }

        private void buttonShow_Click(object sender, EventArgs e)
        {
            MessageBox.Show(((WAYS)_bindingDataProperty.Way_pro).ToString());
        }
    }

    public enum WAYS
    {
        WAY0 = 0x00,
        WAY1 = 0x01,
        WAY2 = 0x02,
        WAY3 = 0x03,
        WAY4 = 0x04,
        WAY5 = 0x05,
        WAY6 = 0x06,
        WAY7 = 0x07,
        WAY8 = 0x08,
        WAY9 = 0x09
    }

    public class BindingDataProperyty : INotifyPropertyChanged
    { 
        #region Way Property
        private WAYS _way = 0;
        public WAYS Way_pro
        {
            get
            {
                return _way;
            }
            set
            {

                if (value == _way)
                {
                    return;
                }
                _way = value;
                NotifyPropertyChanged(() => Way_pro);
            }
        }
        #endregion

        #region Way NotifyPropertyChanged
        public void NotifyPropertyChanged<T>(Expression<Func<T>> property)
        {
            if (PropertyChanged == null)
            {
                return;
            }
            var memberExpression = property.Body as MemberExpression;
            if (memberExpression == null)
            {
                return;
            }

            PropertyChanged.Invoke(this, new PropertyChangedEventArgs(memberExpression.Member.Name));
        }

        public event PropertyChangedEventHandler PropertyChanged;
        #endregion
    }
}
代码正常运行,可是当我在Combox选择了项之后,要显示相应的工作方式时,怪异的事情发生了。请看下图1

图1


我明明在Combox上选择了4,结果一点Show之后,却弹出了WAY0,同时Combox却自动变成了0,这是怎么回事?这时不是应该弹出WAY4才对的吗?

网上搜了一通之后,没有看到合适的解决方案。思来想去,问题可能是出在枚举的绑定上,那就先别用枚举来定义Way_pro了,先用int来。修改的代码如下

    public class BindingDataProperyty : INotifyPropertyChanged
    {
        #region Way Property
        private int _way = 0;
        public int Way_pro
        {
            get
            {
                return _way;
            }
            set
            {

                if (value == _way)
                {
                    return;
                }
                _way = value;
                NotifyPropertyChanged(() => Way_pro);
            }
        }
        #endregion        

       ...
    }


代码中就是把Way_pro的类型由WAYS改成了int.下面是运行结果(图2)

图2


Combox选择了6,Show出来的是WAY6,结果达到了预期。

这么看来,还真的是枚举引起的。目的达到了,但是为什么会引起这个问题,还是没有明白,于是进行了进一步的测试。

将Way_pro的类型再改回成枚举WAYS,同时将初始值改成WAY9.修改的代码如下

    public class BindingDataProperyty : INotifyPropertyChanged
    {
        #region Way Property
        private WAYS _way = WAYS.WAY9;
        public WAYS Way_pro
        {
            get
            {
                return _way;
            }
            set
            {

                if (value == _way)
                {
                    return;
                }
                _way = value;
                NotifyPropertyChanged(() => Way_pro);
            }
        }
        #endregion        
         ...
    }

下面是运行结果(图3)

图3


可以看到Combox的值为9,正是我们所绑定的值WAY9对应的SelectedIndex。这么看来,从枚举到SelectedIndex的绑定是OK的。

再结合前面图1的结果,当我们选择了4之后,Show出来的结果却还是WAY0,同时Combox变成了0.这说明,双向绑定从SelectedIndex到枚举时出错了,导致我们在点击Show时,获取的是Way_pro的默认值(见图4),再次触发Way_pro,将Way_pro的默认值重新绑定到了Combox上,于是Combox又显示了默认值。

图4


那我们怎么证明从SelectedIndex到枚举的绑定出错了呢?我们知道,在双向绑定时,控件上的属性值发生改变时,会触发相应绑定属性的set方法,如SelectedIndex改变会触发Way_pro的set方法,如果不触发那就说明异常了(如类型转换失败引起的异常)。下面是两段代码debug的截图。

图5


图6


从图5中我们可以看到,Combox的默认是WAY9,对应的SelectedIndex是9,当我们在Combox选择了5之后,Way_pro的set方法并没有被触发。而从图6中可以看到,Combox选择了5之后,Way_pro的set方法触发了,并且值value=5也值进去了。这就说明图5的方式出现了异常,所以set方法没有触发,而这个异常是SelectedIndex隐式转换成WAYS时出错了。

如果只是进行单向绑定(也就是只改变Way_pro的值,Combox的SelectedIndex就会相应的改变),是可以直接将枚举与SelectedIndex绑定的。如图7

图7


所以综上,Combox的SelectedIndex与枚举可以直接单向绑定,但是不能直接双向绑定。如果要进行双向绑定,所绑定的属性必须定义成int类型,在取值时再强转成枚举类型。

补充:对于Combox的数据绑定需要使用SelectItem,同时绑定的源需要附一个初始值。如果绑定的是SelectValue或者SelectText,有可能会出问题,特别是直接将数据源赋值到Combox.DataSource中时,SelectValue会为空值。参考代码如下

 private void FormMain_Load(object sender, EventArgs e)
        {
            ...//使用前面的代码
	    _bindingDataProperty.Data_pro=1;//先赋一个初始值
            comboBoxData.DataBindings.Add("SelectedItem",
                                         _bindingDataProperty,
                                         "Data_pro",
                                         false,
                                         DataSourceUpdateMode.OnPropertyChanged);
	   
        }  

private void buttonShow_Click(object sender, EventArgs e)
        {           
            string info = string.Format("Data:{0}", _bindingDataProperty.Data_pro);
            MessageBox.Show(info);
        }

public class BindingDataProperyty : INotifyPropertyChanged
    {

     ...//使用前面的代码

        #region Data Property
        private string Data_ = "";
        public string Data_pro
        {
            get
            {
                return Data_;
            }
            set
            {

                if (value == Data_)
                {
                    return;
                }
                Data_ = value;
                NotifyPropertyChanged(() => Data_pro);
            }
        }
        #endregion

       ...//使用前面的代码
    }


版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

枚举与Combox的SelectedIndex绑定出现怪异问题的解决方案

在Combox中有一系列的选项,其选项的SelectedIndex值对应了相应的枚举值,而这些枚举值会影响着后续的工作模式,所以就想着将Combox的SelectedIndex和枚举值进行双向绑定,代...

以前自学留下来得问题集---你觉得如何呢!

1.在添加数据时,如何防止表单id被篡改?答:为了防止篡改,需要更改模型的属性,增加允许提交的字段信息即可2.在修改数据时,如果别人恶意修改隐藏里面的id,怎么处理?(篡改表单数据)答:解决方案:数字...
  • Fa_Ker
  • Fa_Ker
  • 2016-07-15 00:45
  • 2007

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

以前自学留下来得问题集---你觉得如何呢!

1.在添加数据时,如何防止表单id被篡改?答:为了防止篡改,需要更改模型的属性,增加允许提交的字段信息即可2.在修改数据时,如果别人恶意修改隐藏里面的id,怎么处理?(篡改表单数据)答:解决方案:数字...
  • Fa_Ker
  • Fa_Ker
  • 2016-07-15 00:46
  • 2107

非代码性问题

学习中遇到的问题及解决方案记录下来

学习笔记02—枚举

android培训 java培训 期待与您交流! 学习完枚举会深刻体会到枚举是一种特殊的类。个人感觉理解枚举的实现原理是最重要的。 我们完全可以自己实现与枚举相同功能的特殊类,但java提供了产品...
  • i10mg
  • i10mg
  • 2013-04-11 17:15
  • 380

用C++语言,调用标准C语言编译器编程的库

当我们调用的函数实现是*.c,而不是*.cpp时,往往会出现

关于vc++6.0“打开文件“功能问题的解决方法

关于vc++6.0“打开文件“功能问题的解决方法 一.先下载FileTool.exe 二.安装外接程序 1.    运行 FileTool.Exe ,实际上是解压一个filetool的工程。 ...

HBase与hive整合出现的问题与解决方案

hive整合hbase时,创建hive表语句的时候没有错误但是报错 hive语句 create external table event_logs_20151220(key string, pl ...

Hadoop开发过程中所遇到的那些坑

核心内容: 1、Hadoop开发过程中常见问题即解决方案 在Hadoop开发的过程中,我们总是遇到各种各样的问题,今天就整理总结一下: 万能的解决步骤:6个检查+查看具体日志 在Hadoo...

枚举解决自定义异常

原文地址:http://blog.csdn.net/sunhuwh/article/details/43545329 自定义异常: [java] view plain copy...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)