我正在使用VB / wpf和SQL Server。我不使用mvvm,数据表,按钮,数据集或窗体。在这些条件和几天的搜索中,我找不到从网格中保存数据的最后一步。
我的数据库表跟踪捐款;它有通常的预期领域。以下是我到目前为止的情况:
XAML(摘录):
<Window.Resources>
<CollectionViewSource
Filter="Filter_By_Member"
x:Key="cvsDonations">
</CollectionViewSource>
.....
<DataGrid
AutoGenerateColumns="False"
CanUserReorderColumns="True"
CanUserResizeColumns="True"
CanUserResizeRows="False"
CanUserDeleteRows="True"
FontSize="13"
FontWeight="Normal"
ItemsSource="{Binding Source={StaticResource cvsDonations}}"
Name="dgDonations"
RowHeaderWidth="20"
SelectionUnit="CellOrRowHeader"
SelectionMode="Single">
<DataGrid.Columns>
<DataGridTextColumn
Binding="{Binding Path=DateDue, Converter={StaticResource conDate}, StringFormat='MMM d, yyyy'}"
ElementStyle="{StaticResource styDateBlock}"
Header="Date Due"
IsReadOnly="True"
Width="90">
</DataGridTextColumn>
.....
我的窗口包含一个ComboBox和网格。网格中的行取决于ComboBox中选择的内容。这是执行此操作的代码。
Private Sub Change_Member(sender As Object, e As SelectionChangedEventArgs) Handles cboMembers.SelectionChanged
cvsDonations.View.Refresh()
End Sub
Private Sub Filter_By_Member(sender As Object, e As FilterEventArgs)
Dim PersonID As Long = CLng(cboMembers.SelectedValue)
Dim d As Donation = DirectCast(e.Item, Donation)
If d.PersonID = PersonID Then
e.Accepted = True
Else
e.Accepted = False
End If
End Sub
到目前为止一切正常。我没想到的是如何自动更新底层数据库(使用已经编写和工作的存储过程)。更具体地说,我无法弄清楚要监视的事件以及如何在代码中实现该事件。
底层集合是ObservableCollection(Of Donation),Donation类实现了INotifyPropertyChanged。我已经考虑过观看属性已更改,但每次填充网格时该事件都会被触发,这样看起来似乎不是正确的方法,此外我无法弄清楚如何实际提升相应的事件,即使这是方式去吧。
我已经尝试使用RowEditChanging事件,这似乎是我想要的几乎所有但在提交任何编辑之前被触发,因此当该事件被触发时,该行包含的捐赠具有旧值。
什么是正确的方法,如果我的整体设置应该如何实施?
答案 0 :(得分:0)
我建议这样做 -
你的Donation类应该有一个标志字段,让我们说Is_Dirty跟踪对象是否有修改。 最初在集合中加载项目时,请确保将Is_Dirty设置为false。当用户在网格上进行编辑并触发属性通知时,设置脏标志(来自属性设置器)。
为了保存,我建议使用一个单独的按钮,单击您从集合中查看所有脏对象并将更新传递给数据库。
通过绑定到脏标志,您还可以更改已修改行的外观以供用户识别已修改的行。
您还可以维护State属性,以了解对象是已添加,更新还是已删除。
通常,我将所有这些功能放在一个基类中,我的所有模型类(例如捐赠)都来自该基类。
一些片段让你去......
public abstract class ObservableDomainObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool _isDirty;
public ObservableDomainObject()
{
_state = ObjectState.Added;
_isDirty = true;
}
private ObjectState _state;
/// <summary>
/// Get or Set
/// </summary>
public ObjectState State
{
get { return _state; }
set
{
if (_state != value)
{
_state = value;
RaisePropertyChanged();
}
}
}
public void SetDirty(Boolean isDirty)
{
this.IsDirty = isDirty;
}
/// <summary>
/// Check if the object is modified.
/// </summary>
public bool IsDirty
{
get { return _isDirty; }
set
{
if (_isDirty != value)
{
if (_state != ObjectState.Added && _state != ObjectState.Deleted)
{
this.State = value ? ObjectState.Modified : ObjectState.Unchanged;
}
_isDirty = value;
RaisePropertyChanged();
}
}
}
protected virtual void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
// Change Dirty flag when property changed.
if (propertyName != "IsDirty")
SetDirty(true);
}
}
public enum ObjectState
{
/// <summary>
/// New Record
/// </summary>
Added = 0,
/// <summary>
/// Unchanged after the load
/// </summary>
Unchanged,
/// <summary>
/// Modified
/// </summary>
Modified,
/// <summary>
/// Deleted
/// </summary>
Deleted
}