Dillema with newing an item in WPF MVVM
I have built a form that displays the properties of items contained in an observable collection. This observable collection is in a ViewModel to which the datacontext of the View is bound to.
When the New butt开发者_如何学Goon on the form gets clicked, a new Item gets added to the observable collection, and with the help of the collectionview is set to the current item. The same form is used. This time, because of the new item, the fields are empty.
Now, I want there to be only one new item in the observable collection. Because of this, I need to somehow distinguish between an Item and a New Item.
So, before the New requirement I had the following Observable Collection in my ViewModel:
public ObservableCollection<ItemViewModel> ItemTypes { get; private set; }
But now I need to be able to distinguish between a New Item and an old item. I've been trying to do a couple of things like building a base class, of which I derive Item and New Item, but this seems really wastfull since I can't think of anything to put in the derived classes, they are really only there to help to see if there's one Empty Item in the observable.
What can I do?
Edit
private void CreateNewItemType()
{
if (DoesNewItemTypeAlreadyExist())
{
return;
}
Model.ItemType itemType = new Model.ItemType();
ItemTypeViewModel itemTypeViewModel = new ItemTypeViewModel(itemType)
{
IsNew = true
};
ItemTypes.Add(itemTypeViewModel);
itemTypesCollectionView.MoveCurrentTo(itemTypeViewModel);
}
private bool DoesNewItemTypeAlreadyExist()
{
return ItemTypes.Any(a => a.IsNew == true);
}
Create a bool property on your item (IsDirty for example). When new, IsDirty is False. The first time something is changed, set it to true. Then you can have a check on the command property for your Add button that creates the new item, to check and see if there are any IsDirty = False
items in the collection. If so, then set that item to selected. If not, then add a new item and select it.
In the past what I have done to do change detection is create a dictionary of String, String. The dictionary contains the name of the property and the original value. In the Changing event handler for the property in my model class, I add an add or remove call that checks to see if an item for that property is there, if so, check current value with changing value. Call OnPropertyChanged("IsDirty")
as appropriate.
Is dirty checks to see if there are any items in the dictionary. The beauty is that if you change the values back to their original values, the record will regain it's IsDirty=False status.
Example of implementation
Private Sub OnAddress1Changing(ByVal value As String)
If Not m_dirtyFields.ContainsKey("Address1") Then
AddDirtyField("Address1", Address1)
Else
If m_dirtyFields("Address1") = value Then RemoveDirtyField("Address1")
End If
End Sub
Public m_dirtyFields As New Dictionary(Of String, String)
Private Sub AddDirtyField(ByVal ColName As String, ByVal OrigValue As String)
If Not m_dirtyFields.ContainsKey(ColName) Then
m_dirtyFields.Add(ColName, OrigValue)
OnPropertyChanged("IsDirty")
End If
End Sub
Private Sub RemoveDirtyField(ByVal ColName As String)
If m_dirtyFields.ContainsKey(ColName) Then
m_dirtyFields.Remove(ColName)
End If
OnPropertyChanged("IsDirty")
End Sub
Public ReadOnly Property IsDirty() As Boolean
Get
If m_dirtyFields.Count > 0 Then 'There are items so record is dirty
Return True
Else
Return False
End If
End Get
End Property
精彩评论