自定义 StronglyTyped BindingSource 项添加 [英] Customize StronglyTyped BindingSource Item Addition

查看:26
本文介绍了自定义 StronglyTyped BindingSource 项添加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想自定义将新项目添加到 BindingSource(所有强类型)中,如以下 MSDN 文章所述:

I want to customize the addition of a new item into a BindingSource (all strongly-typed) as described on the following MSDN Article:

如何:使用Windows 窗体绑定源

下面的代码导致 InvalidOperationException:添加到 BindingSource 列表的对象必须都是相同的类型.此外,对象 myTypesBindingSource.Current 似乎是一个 DataRowView,里面有我的相关行.

The code below results in InvalidOperationException: Objects added to a BindingSource's list must all be of the same type. Also, the object myTypesBindingSource.Current seems to be a DataRowView with my relevant row inside.

如何自定义添加强类型BindingSource?

How can I customize the addition of a strongly-typed BindingSource?

private void InitializeComponent()
{
    this.components = new System.ComponentModel.Container();

    this.someDataSet = new myDB.SomeDataSet();
    this.myTypesBindingSource = new System.Windows.Forms.BindingSource(this.components);
    this.myTypesTableAdapter = new myDB.SomeDataSetTableAdapters.myTypesTableAdapter();
    this.tableAdapterManager = new myDB.SomeDataSetTableAdapters.TableAdapterManager();
    this.myTypesBindingNavigator = new System.Windows.Forms.BindingNavigator(this.components);

    this.someIntValueTextBox = new System.Windows.Forms.TextBox();

    // someDataSet
    this.someDataSet.DataSetName = "SomeDataSet";
    this.someDataSet.SchemaSerializationMode = System.Data.SchemaSerializationMode.IncludeSchema;

    // myTypesBindingSource

    // As generated:
    // this.myTypesBindingSource.DataMember = "myTypes";
    // this.myTypesBindingSource.DataSource = this.someDataSet;
    this.myTypesBindingSource.DataSource = this.someDataSet;
    this.myTypesBindingSource.AddingNew += new System.ComponentModel.AddingNewEventHandler(this.myTypesBindingSource_AddingNew);

    // myTypesTableAdapter
    this.myTypesTableAdapter.ClearBeforeFill = true;

    // tableAdapterManager
    this.tableAdapterManager.BackupDataSetBeforeUpdate = false;
    this.tableAdapterManager.myTypesTableAdapter = this.myTypesTableAdapter;
    this.tableAdapterManager.UpdateOrder = myDB.SomeDataSetTableAdapters.TableAdapterManager.UpdateOrderOption.InsertUpdateDelete;

    // someIntValueTextBox
    this.someIntValueTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.myTypesBindingSource, "someIntValue", true));
    this.someIntValueTextBox.Name = "someIntValueTextBox";
}

private void myTypesBindingSource_AddingNew(object sender, AddingNewEventArgs e)
{
    SomeDataSet.myTypesRow newRow = someDataSet.myTypes.NewmyTypesRow();
    newRow.someIntValue = 99;
    e.NewObject = newRow; 
}

推荐答案

在示例中,它不是强类型的 BindingSource.事实上,AddingNewEventArgs.NewObject 属性是一个对象.因此,分配给它任何派生类型都可以.

In the example, it is not a strongly typed BindingSource. As a matter of fact, the AddingNewEventArgs.NewObject property is an object. So, assigning it any derived type shall make it.

另外,请注意该示例使用了一个类对象 DemoCustomer,它不是返回 DataRow.在我看来,当使用 数据集.

Also, notice that the example uses a class object DemoCustomer, it is no DataSet.Tables[0].Row which returns a DataRow. The game is a bit different, in my point of view, when using a DataSet.

当您使用 DataSet 时,您只需设置一个 DataTable 作为 BindingSource.DataSource,让你写一些类似的东西:

When one uses a DataSet, you'll have to set only a DataTable as the BindingSource.DataSource, making you write something like:

BindingSource.DataSource = DataSet.Tables[0];

这样,当您将项目添加到 BindingSource.List 使用 BindingSource.AddNew()BindingSource知道"它有一个 DataTable 作为它的 DataSource,所以它调用 DataTable.NewRow() 方法和一个新的 DataRow已添加到您的 DataTable!因此,有一个 DataRow 来处理而不是一个简单的对象.

This way, when you add an item to the BindingSource.List using BindingSource.AddNew(), the BindingSource "knows" that it has a DataTable as its DataSource, so it calls the DataTable.NewRow() method and a new DataRow is added to your DataTable! Thus, having a DataRow to handle instead of a simple object.

使用 DataRow

Working with a DataRow

如果您想按照 MSDN 上的示例进行操作,则必须自己创建该行.

If you want to do similar to what the example on MSDN says, you'll have to create the row yourself.

DataRow newRow = DataSet.Tables[0].NewRow();
newRow.Columns["intColumn"] = 99;
e.NewObject = newRow;

这样,你就可以知道你想要什么默认值了.

This way, you shall be able to tell what default values you want.

否则,如果没有,你不妨试试这个:

Otherwise, if not, you might as well try this:

var newRow = (DataRow)e.NewObject;
newRow["intColumn"] = 99;

这里的弱点是每当你改变底层数据库表的列名时,你必须来这里,改变你的intColumn的名称,重新编译,重新部署.

The weakness here is whenever you change the underlying database table column name, you'll have to come here, change the name of your intColumn, and recompile, and redeploy.

此外,这种情况不会经常发生,因此根据您的环境背景,这可能是值得的.

Besides, this shall not happen often, so it might be worthy depending on your environmental context.

编辑 #1

关注后:

此外,对象 myTypesBindingSource.Current 似乎是一个 DataRowView,里面有我的相关行

Also, the object myTypesBindingSource.Current seems to be a DataRowView with my relevant row inside

来自 MSDN: DataRowView

每当显示数据时,例如在 DataGrid 控件中,每行只能显示一个版本.显示的行是一个 DataRowView.

Whenever data is displayed, such as in a DataGrid control, only one version of each row can be displayed. The displayed row is a DataRowView.

DataRowView 可以具有四种不同版本状态之一:默认、原始、当前和建议.

A DataRowView can have one of four different version states: Default, Original, Current, and Proposed.

在 DataRow 上调用 BeginEdit 后,任何编辑过的值都将成为建议值.在调用 CancelEdit 或 EndEdit 之前,该行具有原始版本和建议版本.如果调用 CancelEdit,则建议的版本将被丢弃,并且该值恢复为 Original.如果调用 EndEdit,则 DataRowView 不再有 Proposed 版本;相反,建议值变为当前值.默认值仅适用于具有定义了默认值的列的行.

After invoking BeginEdit on a DataRow, any edited value becomes the Proposed value. Until either CancelEdit or EndEdit is invoked, the row has an Original and a Proposed version. If CancelEdit is invoked, the proposed version is discarded, and the value reverts to Original. If EndEdit is invoked, the DataRowView no longer has a Proposed version; instead, the proposed value becomes the current value. Default values are available only on rows that have columns with default values defined.

这意味着在添加新行时,您实际上是在添加一个 DataRowView.您可以通过访问其 DataRowView.Row 属性.

This means that when adding a new row, you're actually adding a DataRowView. You may access the current row by accessing its DataRowView.Row property.

考虑到这一点,您可能会在我对此的最初回答中更改提议的解决方案:

Taking this into consideration, you might perhaps change the proposed solution in my initial answer to this:

var newRow = ((DataRowView)e.NewObject).Row;
newRow.Columns["intColumn"] = 99;

(史蒂文)最终代码

DataView dv = (DataView)myTypesBindingSource.List;
DataRowView drv = dv.AddNew();
SomeDataSet.myTypesRow newMyTypesRow = (SomeDataSet.myTypesRow)drv.Row;
newMyTypesRow.someIntValue = 53;
e.NewObject = drv;
myTypesBindingSource.MoveLast();

这篇关于自定义 StronglyTyped BindingSource 项添加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆