自定义强大的绑定源项目添加 [英] Customize StronglyTyped BindingSource Item Addition

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

问题描述

我想自定义一个新项目添加到 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窗体BindingSource自定义项目添加

下面的代码导致 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 ,它不是 DataSet.Tables [0] .Row 它返回一个 DataRow 。游戏有点不一样,在我看来,当使用 DataSet

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 。目前似乎是一个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,则建议的版本将被丢弃,该值将恢复为原始。如果调用EndEdit,则DataRowView不再具有建议版本;而是建议的值成为当前值。默认值仅在具有定义了默认值的列的行上可用。

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;

编辑:(由Steven)最终代码

(by Steven) Final Code

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

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

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