当前位置:编程学习 > C#/ASP.NET >>

CellValueChanged问题

本人用的是dev公司的gridview控件,但是问题现在是假设单元格时数字型的,假如我进入这个单元格编辑一下,但是编辑前后数字不变也会触发CellValueChanged,但是奇怪的是假如此单元格是个位数则不会触发此事件,2位数以后都会触发此事件,即使没有任何数字变化 --------------------编程问答-------------------- .................是不是软件bug啊 --------------------编程问答-------------------- 应该不是吧,应该是很成熟的公司了 --------------------编程问答--------------------
引用 1 楼 symbol_bc 的回复:
.................是不是软件bug啊
--------------------编程问答-------------------- 无语,怎么解决哦 --------------------编程问答-------------------- --------------------编程问答-------------------- 其实说不上是Bug。这各DEV控件的实现原理差不多。
其实会不会触发CellValueChanged。
以V7.3版本代码观察你会发现与ColumnView.cs中
public override bool PostEditor() {
....
if(ActiveEditor == null || !EditingValueModified || this.fEditingCell == 

null)
....
}中的“EditValueModified” 即值是否被体改有关。
而“EditValueModified”由
public virtual bool EditingValueModified {
get {
...
DevExpress.XtraEditors.BaseEdit baseEdit = ActiveEditor as DevExpress.XtraEditors.BaseEdit;
if(baseEdit != null) {
return baseEdit.IsModified;
....
可知其实取决于BaseEdit中的IsModified.
当你跟跟BaseEdit控件时,你会发现其
OnEditValueChanging事件在的会对IsModified进行更改。
而OnEditValueChanging事件在BaseEdit的EditValue属性的Set方法中调用。
public virtual object EditValue {
            get { return fEditValue; }
            set {
                value = Properties.DoParseEditValue(value).Value;
                FlushPendingEditActions();
                if(EditValue == value) return;    //这行是关键!!!!!!!
                if(CompareEditValue(EditValue, value, false)) return;
                OnEditValueChanging(new ChangingEventArgs(fEditValue, value));
            }
        }
=================================================
由上可知,当你个位数时, 如果值没改变,if(EditValue == value) return; 可知是不会触发事件的。
但当有两位数据,如果一起改,比如 全选“15”,当你输入1时,此时if(EditValue == value)是不成立的,再输入5也是一样(其值在这个过程已改了两次,但网格是在你光标离开时(不限于)以PstEditor方式一次提交),所以会触发CellValueChanged事件。
但即使是两位数,如果你一次只选中一个数据进行改更,同样是不会触发的。
===========================================================

致于如何解决,业务判断一下就好。我认为这不是Bug。其实微软自带的Edit控件,就算你只改一位,也同样会触发TextChanged事件。
--------------------编程问答-------------------- 理是那个理,那怎么解决纳,业务判断??? --------------------编程问答-------------------- 请在修改之后加上 this.validate();你再次获取值时候是你修改后的值而不是 之前的了 

  成功后请加分  谢谢~~ --------------------编程问答-------------------- 还是不懂哦 --------------------编程问答-------------------- --------------------编程问答-------------------- 没人能圆满解决下嘛 --------------------编程问答-------------------- 这个楼主很懒 我是8楼的 成功了吗 成功了 就请加分 啊~~ 我在公司用的也是这种控件。。操作还算是熟悉。。。。。。。 --------------------编程问答-------------------- 首先,在不改控件代码的前提下是无法更变这个事件的触发因素。所以就只能从业务逻辑进行控制。
很遗憾楼主并没有说清楚,所以也很难提出更好的解决方案。
楼主最好说明一下想干什么?是不是可以采用其它方式来绕过这个事件。因为这个事件只是告诉用户其中的内容是改过的,但并不代码最终结果一样。 --------------------编程问答-------------------- 以前也遇到过一个类似的问题..就是按一个数字或字母,第一次可以,得第二次再按同样的字母就不能用了.试试是这个原因吗? --------------------编程问答-------------------- 给了点源码,看看有没有帮助

//本页面放了一个网格控件,其中第一列显示学生名,第二列显示学生年龄
public partial class Form1 : Form
    {
        class Student
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        List<Student> stds = new List<Student>();
        public Form1()
        {
            InitializeComponent();

            stds.Add(new Student() { Name = "Std1", Age = 5 });
            stds.Add(new Student() { Name = "Std2", Age = 15 });

            this.gridControl1.DataSource = stds;

        }

        private void gridView1_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
        {
          //获取数据集中的行
            int rowIndex = gridView1.GetDataSourceRowIndex(e.RowHandle);            

            //业务判断是否更新
            if (IsChanged(e.Value, e.Column.Name, rowIndex))
            {
                MessageBox.Show("年龄已更改");
            }
            else
            {
                MessageBox.Show("年龄其实没变");
            }

        }

        //只作说明,细节自已
        bool IsChanged(object value, string columnName, int sourceIndex)
        {
            var std = stds[sourceIndex];
            if (columnName == "gridColumn1")   //以设计器中的名字为准,默认第一列
            {
            }
            else if (columnName == "gridColumn2")
            {
                //只判断年龄是否更新
                if (std.Age.ToString() != value.ToString())  //
                {
                    return true;
                }

            }
            return false;
        }
--------------------编程问答-------------------- 补充,经测试上面的代码有误。
因为DataSource对应的stds已经更新,所以判断不出来。
可以为stds拷由一份原始数据时行比较。
当然这个备份数据的同步也要注意。

以上只提供一重思路,解决应该没问题。

--------------------编程问答--------------------

public partial class Form1 : Form
    {
        class Student
        {
            public string Name { get; set; }
            public int Age { get; set; }

            public Student Copy()
            {
                return new Student() { Name = this.Name, Age = this.Age };
            }
        }
        
        List<Student> stds = new List<Student>();
        List<Student> copyStds = new List<Student>();

        public Form1()
        {
            InitializeComponent();

            stds.Add(new Student() { Name = "Std1", Age = 5 });
            stds.Add(new Student() { Name = "Std2", Age = 15 });

            foreach (var temp in stds)
            {
                copyStds.Add(temp.Copy());
            }

            this.gridControl1.DataSource = stds;

        }

        private void gridView1_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
        {
            //获取数据集中的行
            int rowIndex = gridView1.GetDataSourceRowIndex(e.RowHandle);            

            //判断是否更新
            if (IsChanged(e.Value, e.Column.Name, rowIndex))
            {
                MessageBox.Show("年龄已更改");
            }
            else
            {
                MessageBox.Show("年龄其实没变");
            }

        }

        //只作说明,细节自已
        bool IsChanged(object value, string columnName, int sourceIndex)
        {
            var std = copyStds[sourceIndex];
            if (columnName == "gridColumn1")   //以设计器中的名字为准,默认第一列
            {
            }
            else if (columnName == "gridColumn2")
            {
                //只判断年龄是否更新
                int age = Convert.ToInt32(value.ToString());
                if (std.Age != age)  //
                {
                    std.Age = age;
                    return true;
                }

            }
            return false;
        }

}
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,