如何处理其他绑定形式的计算字段?
How to handle calculated fields in otherwise bound forms?
这涉及表单上的批准字段。在数据库中,它是一个 bool 字段,一个包含批准者 FK 的 int 字段,以及一个日期时间字段,它们一起指示某事是否已获批准,如果是,则由谁批准以及何时批准。在表格上,这必须翻译成类似“John Smith 于 01/02/03 04:05 批准的内容。”
我用导航栏来处理这个问题。当绑定源位置改变时,事件被捕获,代码格式化计算字段,像这样(代码做什么并不重要)。
private void ctlNavBar1_displayCurrent(object sender, EventArgs e)
{
var drv = talsBindingSource.Current as DataRowView;
if (drv != null)
{
ctlBoundCheckButton1.lblText = $"Submitted {drv.Row.Field<DateTime>("SubmitDate").ToString("MM/dd/yy hh:mm tt")}";
ctlBoundCheckButton1.setControls(true);
if (drv.Row.Field<bool>("Approved"))
{
var sup = talsSupervisorsBindingSource.Current as DataRowView;
ctlBoundCheckButton2.lblText = $"Approved by {sup.Row.Field<string>("FullName")} on {drv.Row.Field<DateTime>("ApproveDate").ToString("MM/dd/yy")}";
ctlBoundCheckButton2.setControls(true);
}
}
else
{
using (DialogCenteringService centeringService = new DialogCenteringService(this))
{
MessageBox.Show("No TALs to Approve", "Confirm", MessageBoxButtons.OK);
}
Close();
}
}
问题在于
public TALsApprove()
{
InitializeComponent();
talsTableAdapter.FillForApproval(timeTrackDataSet.TALs, User.ID);
usersTableAdapter.FillBySupervisor(timeTrackDataSet.Users, User.ID);
timeSlipsTableAdapter.FillBySupervisor(timeTrackDataSet.TimeSlips, User.ID);
ctlNavBar1.displayCurrent += ctlNavBar1_displayCurrent;
ctlNavBar1.bindingSource = talsBindingSource;
// this assignment doesn't fire Position Changed (or anything else, as far as I can tell)
}
首次分配绑定源时,不会触发绑定源事件 PositionChanged。我已经通过使用表单 Shown 事件解决了这个问题,就像这样。
private void TALsApprove_Shown(object sender, EventArgs e)
{
ctlNavBar1_displayCurrent(null, new EventArgs());
}
所以我的问题是:
1.- 像这样直接调用事件处理程序是否会扰乱 .NET 的内部结构? (例如内存泄漏、堆栈问题等)
2.- 在绑定源首次初始化时以及当前记录的内容发生变化时,是否有更简单的方法来处理字段的计算?我尝试了绑定源事件 CurrentChanged 和 CurrentItemChanged,但它们似乎过火了,甚至在实际字段值没有更改时也会触发。
我可能会想到几种方法来整理它:
1 ) 使用计算列
假设:
- 您有一个强类型数据集,其中包含两个 table 应用程序和用户
- 您在应用程序中有以下列:Approved(bool)、ApproveDate(datetime)、ApprovedByUserId(int)
- 您在应用程序和用户之间有一个数据关系,将 Applications.ApprovedByUserId(许多)映射到 User.UserId(一个),并且 UserId 也是一个 int
进程:
- 在您的数据集中单击您的应用程序 table,然后添加一个字符串列
- 将其表达式 属性 设置为类似于:
IIF([Approved] = False,'Not approved','Approved by' + Parent.Username + ' on ' + [ApproveDate])
您已经有一些进程可以将良好的数据填充到 table:
当您 运行 应用程序成为数据 table 构建叙述的问题时:
让我们在 运行 时间编辑另一个细节:
当您完成编辑并移出该行后,它将被提交到 table 并且叙述会自动更新
中详细了解可以使用的语法
如果您没有批准布尔值,您可以添加一个或使用其他测试,例如 IIF(ApprovedByUserId IS NULL,'Not Appproved,'App...'). If yo uhave multiple datarelations coming off Applications you specify the name of the relation after Parent like
Parent(App_User).UserName` 假设数据关系被称为 App_User
- 在 UI
上绑定不同的东西
没有人说过你只需要绑定文本。如果你的数据集中有一个“已批准”的布尔列,你可以在一行中有多个标签:
--label1----- --label2------ --label3-- --label4--
"Approved by" BindParentName " on " BindDate
您可以将它们的每一个 Visible 属性绑定到 Approved 布尔值,以便在用户导航到未批准的行时标签消失。
将父用户名放入应用程序数据中的最简单方法 table(因为所有这些标签都绑定到位于应用程序 table 上的 indingsource,对吗?)是使用Expression
在新列上,如上,但更简单(只需 Parent.UserName
或 Parent(App_User).UserName`)将用户名导入应用程序数据 table。
还有其他方法,涉及绑定到数据关系的多个绑定源。我们甚至可以轻摇组合框来完成它 - 组合有用户的数据源 table,但数据成员为“来自应用程序 table 的 ApprovedByUserId”;它将执行 ApprovedByUserId <--> UserId
等价
的 2 种方式查找
这涉及表单上的批准字段。在数据库中,它是一个 bool 字段,一个包含批准者 FK 的 int 字段,以及一个日期时间字段,它们一起指示某事是否已获批准,如果是,则由谁批准以及何时批准。在表格上,这必须翻译成类似“John Smith 于 01/02/03 04:05 批准的内容。”
我用导航栏来处理这个问题。当绑定源位置改变时,事件被捕获,代码格式化计算字段,像这样(代码做什么并不重要)。
private void ctlNavBar1_displayCurrent(object sender, EventArgs e)
{
var drv = talsBindingSource.Current as DataRowView;
if (drv != null)
{
ctlBoundCheckButton1.lblText = $"Submitted {drv.Row.Field<DateTime>("SubmitDate").ToString("MM/dd/yy hh:mm tt")}";
ctlBoundCheckButton1.setControls(true);
if (drv.Row.Field<bool>("Approved"))
{
var sup = talsSupervisorsBindingSource.Current as DataRowView;
ctlBoundCheckButton2.lblText = $"Approved by {sup.Row.Field<string>("FullName")} on {drv.Row.Field<DateTime>("ApproveDate").ToString("MM/dd/yy")}";
ctlBoundCheckButton2.setControls(true);
}
}
else
{
using (DialogCenteringService centeringService = new DialogCenteringService(this))
{
MessageBox.Show("No TALs to Approve", "Confirm", MessageBoxButtons.OK);
}
Close();
}
}
问题在于
public TALsApprove()
{
InitializeComponent();
talsTableAdapter.FillForApproval(timeTrackDataSet.TALs, User.ID);
usersTableAdapter.FillBySupervisor(timeTrackDataSet.Users, User.ID);
timeSlipsTableAdapter.FillBySupervisor(timeTrackDataSet.TimeSlips, User.ID);
ctlNavBar1.displayCurrent += ctlNavBar1_displayCurrent;
ctlNavBar1.bindingSource = talsBindingSource;
// this assignment doesn't fire Position Changed (or anything else, as far as I can tell)
}
首次分配绑定源时,不会触发绑定源事件 PositionChanged。我已经通过使用表单 Shown 事件解决了这个问题,就像这样。
private void TALsApprove_Shown(object sender, EventArgs e)
{
ctlNavBar1_displayCurrent(null, new EventArgs());
}
所以我的问题是:
1.- 像这样直接调用事件处理程序是否会扰乱 .NET 的内部结构? (例如内存泄漏、堆栈问题等)
2.- 在绑定源首次初始化时以及当前记录的内容发生变化时,是否有更简单的方法来处理字段的计算?我尝试了绑定源事件 CurrentChanged 和 CurrentItemChanged,但它们似乎过火了,甚至在实际字段值没有更改时也会触发。
我可能会想到几种方法来整理它:
1 ) 使用计算列
假设:
- 您有一个强类型数据集,其中包含两个 table 应用程序和用户
- 您在应用程序中有以下列:Approved(bool)、ApproveDate(datetime)、ApprovedByUserId(int)
- 您在应用程序和用户之间有一个数据关系,将 Applications.ApprovedByUserId(许多)映射到 User.UserId(一个),并且 UserId 也是一个 int
进程:
- 在您的数据集中单击您的应用程序 table,然后添加一个字符串列
- 将其表达式 属性 设置为类似于:
IIF([Approved] = False,'Not approved','Approved by' + Parent.Username + ' on ' + [ApproveDate])
您已经有一些进程可以将良好的数据填充到 table:
当您 运行 应用程序成为数据 table 构建叙述的问题时:
让我们在 运行 时间编辑另一个细节:
当您完成编辑并移出该行后,它将被提交到 table 并且叙述会自动更新
中详细了解可以使用的语法如果您没有批准布尔值,您可以添加一个或使用其他测试,例如 IIF(ApprovedByUserId IS NULL,'Not Appproved,'App...'). If yo uhave multiple datarelations coming off Applications you specify the name of the relation after Parent like
Parent(App_User).UserName` 假设数据关系被称为 App_User
- 在 UI 上绑定不同的东西
没有人说过你只需要绑定文本。如果你的数据集中有一个“已批准”的布尔列,你可以在一行中有多个标签:
--label1----- --label2------ --label3-- --label4--
"Approved by" BindParentName " on " BindDate
您可以将它们的每一个 Visible 属性绑定到 Approved 布尔值,以便在用户导航到未批准的行时标签消失。
将父用户名放入应用程序数据中的最简单方法 table(因为所有这些标签都绑定到位于应用程序 table 上的 indingsource,对吗?)是使用Expression
在新列上,如上,但更简单(只需 Parent.UserName
或 Parent(App_User).UserName`)将用户名导入应用程序数据 table。
还有其他方法,涉及绑定到数据关系的多个绑定源。我们甚至可以轻摇组合框来完成它 - 组合有用户的数据源 table,但数据成员为“来自应用程序 table 的 ApprovedByUserId”;它将执行 ApprovedByUserId <--> UserId
等价