MVVM मैं WPF & करने के लिए कुछ बुनियादी कार्यशीलता के साथ संघर्ष कर नया होने के नाते को बचाने के लिए एक ModelView करने के लिए 'IsDirty' कार्यक्षमता को लागू करने।MVVM - आदेश डेटा
मुझे पहले की व्याख्या क्या मैं के बाद कर रहा हूँ, और फिर कुछ उदाहरण कोड देते हैं ...
मैं उपयोगकर्ताओं की सूची दिखा एक स्क्रीन है, और मुझे दाएँ हाथ पर चयनित उपयोगकर्ता के विवरण प्रदर्शित संपादन योग्य टेक्स्टबॉक्स के साथ पक्ष। मेरे पास एक बचत बटन है जो डेटाबाउंड है, लेकिन डेटा को वास्तव में बदलते समय मुझे यह बटन प्रदर्शित करना होगा। यानी - मुझे "गंदे डेटा" की जांच करने की आवश्यकता है।
मैं एक पूरी तरह से MVVM उदाहरण है, जिसमें मैं एक मॉडल उपयोगकर्ता कहा जाता है है:
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()
{
}
}
}
"RelayCommand" सिर्फ एक सरल आवरण है:
namespace Test.Model
{
class User
{
public string UserName { get; set; }
public string Surname { get; set; }
public string Firstname { get; set; }
}
}
फिर, ViewModel इस तरह दिखता है कक्षा, जैसा कि "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()
{
}
}
}
- XAML
<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>
तो बुनियादी तौर पर, जब मैं एक उपनाम संपादित करें, सहेजें बटन सक्षम होगा; और यदि मैं अपना संपादन पूर्ववत करता हूं - ठीक है तो इसे फिर से अक्षम किया जाना चाहिए क्योंकि कुछ भी नहीं बदला है।
मैं कई उदाहरण में यह देखा है, लेकिन अभी तक बाहर नहीं मिला है यह कैसे करना है।
किसी भी मदद की बहुत सराहना की जाएगी! ब्रेंडन
मैं एमवीवीएम लाइट टूलकिट के साथ-साथ –
का उपयोग करता हूं धन्यवाद, मैंने एमवीवीएम-लाइट टूलकिट स्थापित किया है, लेकिन मैंने "IsDirty" कार्यक्षमता को आसानी से कार्यान्वित करने का कोई तरीका नहीं देखा है। हालांकि मैंने अपनी समस्या को हल करने में कामयाब रहा है (शायद सबसे अच्छा तरीका नहीं - लेकिन यह काम करता है) - – Brendan
विवरण के साथ थोड़ी देर बाद मेरे अपने प्रश्न का उत्तर देगा एमवीवीएम गंदे पढ़ने की कार्यक्षमता का समर्थन नहीं करता है। एमवीवीएम पैटर्न को लागू करने के प्रयास को कम करने के लिए यह केवल एक सुझाव था। यह जानना अच्छा है कि आपने पहले ही गंदा पढ़ा है। अब मैं हल्के टूलकिट में कमांडिंग के लिए आगे संदेश और घटना का पता लगाने का सुझाव दूंगा जो आपको अधिक नियंत्रण देगा। आपका समय अच्छा गुजरे। – ShahidAzim