gpt4 book ai didi

validation - Xamarin MvvmCross ViewModel 验证

转载 作者:行者123 更新时间:2023-12-04 02:40:36 25 4
gpt4 key购买 nike

我目前正在构建我的第一个 Xamarin MvvmCross 应用程序,我目前正在研究验证用户对 View 模型的输入。

围绕此插件的所有链接(包括 MvvmCross 团队)进行大量搜索:

MVVMCross.Plugins.Validation

这个插件使用了一个非常旧的 MvvmCross v3 版本。我已经尝试从这个插件中获取代码并将其直接构建到我的应用程序核心项目中,直到我遇到 Bindings 重大更改。然后我得出的结论是,这个插件实际上需要完全重写才能使用最新版本的 MvvmCross。

所以我现在有点卡住了。

目前推荐的在 View 模型中执行输入验证的最佳方法是什么?

最佳答案

编辑:在 GitHub 上添加示例项目 https://github.com/kiliman/mvx-samples/tree/master/MvxSamples.Validation

我使用 MVVM 验证助手 http://www.nuget.org/packages/MvvmValidation/

这是一个简单易用的验证库。它与 MvvmCross 无关。

以下是我使用它的方式,例如,在我的 SigninViewModel 中:

private async void DoSignin()
{
try
{
if (!Validate())
{
return;
}

IsBusy = true;
Result = "";
var success = await SigninService.SigninAsync(Email, Password);

if (success)
{
Result = "";
ShowViewModel<HomeViewModel>();
Close();
return;
}

Result = "Invalid email/password. Please try again.";
}
catch (Exception ex)
{
Result = "Error occured during sign in.";
Mvx.Error(ex.ToString());
}
finally
{
IsBusy = false;
}
}

private bool Validate()
{
var validator = new ValidationHelper();
validator.AddRequiredRule(() => Email, "Email is required.");
validator.AddRequiredRule(() => Password, "Password is required.");

var result = validator.ValidateAll();

Errors = result.AsObservableDictionary();

return result.IsValid;
}

它的好处是您可以将错误作为集合并将它们绑定(bind)到您的 View 中。对于 Android,我将 Error 属性设置为键控错误消息。
<EditText
android:minHeight="40dp"
android:layout_margin="4dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="Email"
local:MvxBind="Text Email; Error Errors['Email']"
android:id="@+id/EmailEditText" />
<EditText
android:minHeight="40dp"
android:layout_margin="4dp"
android:inputType="textPassword"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Password"
local:MvxBind="Text Password; Error Errors['Password']"
android:id="@+id/PasswordEditText" />

这是验证的样子:

Validation message

编辑:显示帮助代码

public static class ValidationResultExtension
{
public static ObservableDictionary<string, string> AsObservableDictionary(this ValidationResult result)
{
var dictionary = new ObservableDictionary<string, string>();
foreach (var item in result.ErrorList)
{
var key = item.Target.ToString();
var text = item.ErrorText;
if (dictionary.ContainsKey(key))
{
dictionary[key] = dictionary.Keys + Environment.NewLine + text;
}
else
{
dictionary[key] = text;
}
}
return dictionary;
}
}

public class ObservableDictionary<TKey, TValue> : IDictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged
{
private const string CountString = "Count";
private const string IndexerName = "Item[]";
private const string KeysName = "Keys";
private const string ValuesName = "Values";

private IDictionary<TKey, TValue> _dictionary;

protected IDictionary<TKey, TValue> Dictionary
{
get { return _dictionary; }
}

public ObservableDictionary()
{
_dictionary = new Dictionary<TKey, TValue>();
}

public ObservableDictionary(IDictionary<TKey, TValue> dictionary)
{
_dictionary = new Dictionary<TKey, TValue>(dictionary);
}

public ObservableDictionary(IEqualityComparer<TKey> comparer)
{
_dictionary = new Dictionary<TKey, TValue>(comparer);
}

public ObservableDictionary(int capacity)
{
_dictionary = new Dictionary<TKey, TValue>(capacity);
}

public ObservableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
{
_dictionary = new Dictionary<TKey, TValue>(dictionary, comparer);
}

public ObservableDictionary(int capacity, IEqualityComparer<TKey> comparer)
{
_dictionary = new Dictionary<TKey, TValue>(capacity, comparer);
}

#region IDictionary<TKey,TValue> Members

public void Add(TKey key, TValue value)
{
Insert(key, value, true);
}

public bool ContainsKey(TKey key)
{
return Dictionary.ContainsKey(key);
}

public ICollection<TKey> Keys
{
get { return Dictionary.Keys; }
}

public bool Remove(TKey key)
{
if (key == null)
{
throw new ArgumentNullException("key");
}

TValue value;
Dictionary.TryGetValue(key, out value);
var removed = Dictionary.Remove(key);
if (removed)
{
OnCollectionChanged(NotifyCollectionChangedAction.Remove, new KeyValuePair<TKey, TValue>(key, value));
}
return removed;
}

public bool TryGetValue(TKey key, out TValue value)
{
return Dictionary.TryGetValue(key, out value);
}

public ICollection<TValue> Values
{
get { return Dictionary.Values; }
}

public TValue this[TKey key]
{
get
{
return Dictionary.ContainsKey(key) ? Dictionary[key] : default(TValue);
}
set
{
Insert(key, value, false);
}
}

#endregion IDictionary<TKey,TValue> Members

public void Add(KeyValuePair<TKey, TValue> item)
{
Insert(item.Key, item.Value, true);
}

public void Clear()
{
if (Dictionary.Count > 0)
{
Dictionary.Clear();
OnCollectionChanged();
}
}

public bool Contains(KeyValuePair<TKey, TValue> item)
{
return Dictionary.Contains(item);
}

public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
Dictionary.CopyTo(array, arrayIndex);
}

public int Count
{
get { return Dictionary.Count; }
}

public bool IsReadOnly
{
get { return Dictionary.IsReadOnly; }
}

public bool Remove(KeyValuePair<TKey, TValue> item)
{
return Remove(item.Key);
}

public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return Dictionary.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)Dictionary).GetEnumerator();
}

public event NotifyCollectionChangedEventHandler CollectionChanged;

public event PropertyChangedEventHandler PropertyChanged;

public void AddRange(IDictionary<TKey, TValue> items)
{
if (items == null)
{
throw new ArgumentNullException("items");
}

if (items.Count > 0)
{
if (Dictionary.Count > 0)
{
if (items.Keys.Any((k) => Dictionary.ContainsKey(k)))
{
throw new ArgumentException("An item with the same key has already been added.");
}
else
{
foreach (var item in items)
{
Dictionary.Add(item);
}
}
}
else
{
_dictionary = new Dictionary<TKey, TValue>(items);
}

OnCollectionChanged(NotifyCollectionChangedAction.Add, items.ToArray());
}
}

private void Insert(TKey key, TValue value, bool add)
{
if (key == null)
{
throw new ArgumentNullException("key");
}

TValue item;
if (Dictionary.TryGetValue(key, out item))
{
if (add)
{
throw new ArgumentException("An item with the same key has already been added.");
}
if (Equals(item, value))
{
return;
}
Dictionary[key] = value;

OnCollectionChanged(NotifyCollectionChangedAction.Replace, new KeyValuePair<TKey, TValue>(key, value), new KeyValuePair<TKey, TValue>(key, item));
}
else
{
Dictionary[key] = value;

OnCollectionChanged(NotifyCollectionChangedAction.Add, new KeyValuePair<TKey, TValue>(key, value));
}
}

private void OnPropertyChanged()
{
OnPropertyChanged(CountString);
OnPropertyChanged(IndexerName);
OnPropertyChanged(KeysName);
OnPropertyChanged(ValuesName);
}

protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

private void OnCollectionChanged()
{
OnPropertyChanged();
if (CollectionChanged != null)
{
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}

private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> changedItem)
{
OnPropertyChanged();
if (CollectionChanged != null)
{
CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, changedItem));
}
}

private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> newItem, KeyValuePair<TKey, TValue> oldItem)
{
OnPropertyChanged();
if (CollectionChanged != null)
{
CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, newItem, oldItem));
}
}

private void OnCollectionChanged(NotifyCollectionChangedAction action, IList newItems)
{
OnPropertyChanged();
if (CollectionChanged != null)
{
CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, newItems));
}
}
}

关于validation - Xamarin MvvmCross ViewModel 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30778812/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com