WPFS를 처음 사용하는 사람 & MVVM 일부 기본 기능에 어려움을 겪고 있습니다.MVVM - 데이터를 저장하기 위해 ModelView에 'IsDirty'기능을 구현합니다.
나는 사용자의 목록을 보여주는 화면을 가지고 있고, 나는 오른쪽에 선택한 사용자의 세부 정보를 표시 ... 내가 먼저 난 후 나는 다음 몇 가지 예제 코드를 첨부 무엇인지 설명
하자 편집 가능한 텍스트 상자가있는 쪽. 그런 다음 DataBound 인 저장 단추가 있지만 데이터가 실제로 변경되었을 때만이 단추를 표시하는 것이 좋습니다. ie - "더티 데이터"를 확인해야합니다.
나는이 모델이 사용자라고 보유하고있는 완전 MVVM 예를 :
은 "RelayCommand"using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows.Input;
using Test.Model;
namespace Test.ViewModel
{
class UserViewModel : ViewModelBase
{
//Private variables
private ObservableCollection<User> _users;
RelayCommand _userSave;
//Properties
public ObservableCollection<User> User
{
get
{
if (_users == null)
{
_users = new ObservableCollection<User>();
//I assume I need this Handler, but I am stuggling to implement it successfully
//_users.CollectionChanged += HandleChange;
//Populate with users
_users.Add(new User {UserName = "Bob", Firstname="Bob", Surname="Smith"});
_users.Add(new User {UserName = "Smob", Firstname="John", Surname="Davy"});
}
return _users;
}
}
//Not sure what to do with this?!?!
//private void HandleChange(object sender, NotifyCollectionChangedEventArgs e)
//{
// if (e.Action == NotifyCollectionChangedAction.Remove)
// {
// foreach (TestViewModel item in e.NewItems)
// {
// //Removed items
// }
// }
// else if (e.Action == NotifyCollectionChangedAction.Add)
// {
// foreach (TestViewModel item in e.NewItems)
// {
// //Added items
// }
// }
//}
//Commands
public ICommand UserSave
{
get
{
if (_userSave == null)
{
_userSave = new RelayCommand(param => this.UserSaveExecute(), param => this.UserSaveCanExecute);
}
return _userSave;
}
}
void UserSaveExecute()
{
//Here I will call my DataAccess to actually save the data
}
bool UserSaveCanExecute
{
get
{
//This is where I would like to know whether the currently selected item has been edited and is thus "dirty"
return false;
}
}
//constructor
public UserViewModel()
{
}
}
}
는 단순한 래퍼입니다 :
namespace Test.Model
{
class User
{
public string UserName { get; set; }
public string Surname { get; set; }
public string Firstname { get; set; }
}
}
그런 다음 뷰 모델은 다음과 같습니다 클래스와 마찬가지로 "ViewModelBase"입니다. 마지막으로
using System;
using System.ComponentModel;
namespace Test.ViewModel
{
public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable
{
protected ViewModelBase()
{
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
public void Dispose()
{
this.OnDispose();
}
protected virtual void OnDispose()
{
}
}
}
을 (난 그냥 선명도 불구하고 후자를 첨부 할 것) - 나는 성을 편집 할 때
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:Test.ViewModel"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<vm:UserViewModel/>
</Window.DataContext>
<Grid>
<ListBox Height="238" HorizontalAlignment="Left" Margin="12,12,0,0" Name="listBox1" VerticalAlignment="Top"
Width="197" ItemsSource="{Binding Path=User}" IsSynchronizedWithCurrentItem="True">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Firstname}"/>
<TextBlock Text="{Binding Path=Surname}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Label Content="Username" Height="28" HorizontalAlignment="Left" Margin="232,16,0,0" Name="label1" VerticalAlignment="Top" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="323,21,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" Text="{Binding Path=User/UserName}" />
<Label Content="Surname" Height="28" HorizontalAlignment="Left" Margin="232,50,0,0" Name="label2" VerticalAlignment="Top" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="323,52,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" Text="{Binding Path=User/Surname}" />
<Label Content="Firstname" Height="28" HorizontalAlignment="Left" Margin="232,84,0,0" Name="label3" VerticalAlignment="Top" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="323,86,0,0" Name="textBox3" VerticalAlignment="Top" Width="120" Text="{Binding Path=User/Firstname}" />
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="368,159,0,0" Name="button1" VerticalAlignment="Top" Width="75" Command="{Binding Path=UserSave}" />
</Grid>
</Window>
그래서 기본적으로, 저장 버튼이 활성화되어야 XAML을; 편집을 취소하면 잘 변경된 것이므로 아무것도 다시 사용하지 않아야합니다.
나는 많은 예제에서 이것을 보았지만 아직 어떻게하는지 알지 못했습니다.
도움이 될 것입니다. 브렌든
MVVM Light Toolkit도 사용합니다. –
감사합니다. MVVM-Light 툴킷을 설치했지만 "IsDirty"기능을 쉽게 구현할 수있는 방법이 없습니다. 그러나 나는 문제를 해결할 수 있었다. (아마도 최선의 방법은 아니지만 작동한다.) - 내 자신의 질문에 약간의 세부 사항으로 대답 할 것이다. – Brendan
MVVM은 더티 읽기 기능을 지원하지 않는다. MVVM 패턴을 구현하기위한 노력을 최소화하기위한 제안 일뿐입니다. 이미 더러운 읽기를 연습 한 것을 알아두면 좋습니다. 이제는 라이트 툴킷에서 더 많은 제어권을 줄 수있는 추가 메시징 및 이벤트를 탐구해볼 것을 제안합니다. 즐거운 시간 되십시오. – ShahidAzim