【问题标题】:c# design question - standalone GUI applicationc# design question - 独立的GUI应用程序
【发布时间】:2009-08-03 15:23:53
【问题描述】:

很高兴看到人们在这里掌握了多少知识,这是一个地方的宝藏。 我见过自己为 DataGridView 事件编写代码 - 并将 DataSource 用于后端准备好的 DataTable 对象。

有时用户可以删除行、更新行等,而底层数据将需要再次验证检查。

假设我们有一个 person 类

class Person {
    public string FirstName { get; set; }       
}

假设代码的其他部分处理创建一个 Person 数组。

class Processor {
       public static Person[] Create()
       {
           ....
           ....
           return person[];
       }
}

并且此信息将出现在 DataGridView 上供用户查看。 我尝试过这样的事情:

public static DataTable ToTable(List<Person> list)
{   ...   }

并且在 Person 类中有这个方法 .. 我认为它属于。然后我会将 DataGridView 绑定到该 DataTable,然后用户将看到该数据并执行他们的任务。

但是我已经考虑过使用 BindingList ,但我还没有受过这么多的教育。我是否仍然具有对 DataGridView 进行排序的能力,就像它使用 DataTable 作为数据源一样? BindingList 会由像“PersonCollection”这样的容器类实现,还是 Person 类会自行实现?我想触发一些事件,以便能够以干净的方式修改集合,而无需重置数据源等。用户体验可能会真正受到影响。

我知道修改DataSource DataTable 是个好方法。但有时我需要触发该特定行所引用的相应类中的方法,并且有一个 ugly 额外隐藏列,该列将包含对其他地方现有对象的引用(Person 引用)。

如果你们知道更好的设计解决方案,我会很高兴听到它。 提前致谢,

附言。读完《务实的程序员》,对代码的批判性思考就停不下来了!

狮子座 B.

【问题讨论】:

    标签: c# user-interface


    【解决方案1】:

    创建一个业务对象类。实施 INotifyPropertyChanged。看下面的代码:

    public class Employee:INotifyPropertyChanged
        {
            public Employee(string Name_, string Designation_, DateTime BirthDate_)
            {
                this.Name = Name_;
                this.Designation = Designation_;
                this.BirthDate = BirthDate_;
            }
    
    
            #region INotifyPropertyChanged Members
            public event PropertyChangedEventHandler PropertyChanged;
            #endregion
    
            private void NotifyPropertyChanged(String info)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(info));
                }
            }
    
            [DisplayName("Employee Name")]
            public string Name
            {
                get { return this._Name; }
    
                set
                {
                    if (value != this._Name)
                    {
                        this._Name = value;
                        NotifyPropertyChanged("Name");
                    }
                }
            }
            private string _Name = string.Empty;
    
            [DisplayName("Employee Designation")]
            public string Designation
            {
                get { return this._Designation; }
    
                set
                {
                    if (value != this._Designation)
                    {
                        this._Designation = value;
                        NotifyPropertyChanged("Designation");
                    }
                }
            }
            private string _Designation = string.Empty;
    
            public DateTime BirthDate
            {
                get { return this._BirthDate; }
    
                set
                {
                    if (value != this._BirthDate)
                    {
                        this._BirthDate = value;
                        NotifyPropertyChanged("BirthDate");
                    }
                }
            }
            private DateTime _BirthDate = DateTime.Today;
    
            [DisplayName("Age")]
            public int Age
            {
                get
                {
                    return DateTime.Today.Year - this.BirthDate.Year;
                }
            }
      }
    

    创建您的自定义集合:

    public class EmployeeCollection:BindingList<Employee>
        {
            public new void  Add(Employee emp)
            {
                base.Add(emp);
            }
    
            public void SaveToDB()
            {
               //code to save to db
            }
        }
    

    设置数据源:

     _employeeStore = new EmployeeCollection(); 
    this.dataGridView1.DataBindings.Add("DataSource", this, "EmployeeStore");
    

    现在,如果您想将员工添加到您的 datagridview,

    Employee employee = new Employee(textBoxName.Text, textBoxDesignation.Text, dateTimePicker1.Value);            
    _employeeStore.Add(employee);
    

    这很干净。您只需使用业务对象,无需触摸 UI。

    【讨论】:

    • INotifyPropertyChanged 是为了确保您对列表所做的更改流向 UI。此外,您还可以让您的 BO 类实现 IDataErrorInfo 以获取 UI 可以捕获的自定义错误信息。这样,您将在业务逻辑代码中进行所有验证。
    • 当您执行 DataBindings.Add.. 时,我们假设 Form 对象中有一个名为 EmployeeStore 的属性,对吗?
    • 不能像我对 DataTable 所做的那样自动对数据网格进行排序..:(
    • 我看过排序 - 覆盖 BindingList 排序函数 - 耶!但这看起来不错。
    • 是的,您必须创建一个名为 EmployeeStore 的属性,该属性返回 _employeeStore。
    【解决方案2】:

    没有完整阅读你的问题,但你可能想看看我的项目ModelShredder,它提供了一种方便快捷的 ToDataTable 方法

    【讨论】:

    • 这很漂亮。我认为我需要对如何将成员读入表格有很大的权力。这不是简单的成员到列的转移;我需要在 UI 中更改变量时手动调用业务方法。并且“修改匿名方法将停止当前的调试会话..”非常烦人。感谢您的提示,我会记住的。
    • 您当然可以通过类似 DataLoadOption 的接口控制您的模型如何转换为 DataTable。我将很快添加对将对象转换为简单数据集(具有关系的表,考虑简单的反向 ORM)的支持
    猜你喜欢
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-10
    • 2011-05-06
    • 1970-01-01
    相关资源
    最近更新 更多