以下のコードを使用して、無効なセルエントリをトラップできます。食料品買い物リストのこの単純な例では、GroceryItem.Name
を記入するだけで済みます。重複したエントリを防ぐためのDatagrid検証
私が今したいことは、そのエントリーがまだ存在していないことを検証する機能を追加することです。既に存在する場合は、同じセルエントリを強調表示したいが、適切なメッセージを表示したい。したがって、ユーザーが「Eggs」を再度入力すると、セルのエラーメッセージは「Eggs is already on the list」でなければなりません。
アイテムビューモデルはコンテナビューモデルについて知ってはいけません。したがって、「名前」プロパティのセルの検証中に重複したエントリがどこで確認できますか?コレクション
項目は
public class GroceryItem : ObservableObject, IDataErrorInfo
{
#region Properties
/// <summary>The name of the grocery item.</summary>
public string Name
{
get { return _name; }
set
{
_name = value;
RaisePropertyChangedEvent("Name");
}
}
private string _name;
#endregion
#region Implementation of IDataErrorInfo
public string this[string columnName] {
get {
if (columnName == "Name") {
if (string.IsNullOrEmpty(Name))
return "The name of the item to buy must be entered";
}
return string.Empty;
}
}
public string Error { get { ... } }
#endregion
}
ビューモデルは、コレクションのDataGridのバインディング
public class MainWindowViewModel : ViewModelBase
{
/// <summary>A grocery list.</summary>
public ObservableCollection<GroceryItem> GroceryList
{
get { return _groceryList; }
set
{
_groceryList = value;
RaisePropertyChangedEvent("GroceryList");
}
}
private ObservableCollection<GroceryItem> _groceryList;
/// <summary>The currently-selected grocery item.</summary>
public GroceryItem SelectedItem { get; [UsedImplicitly] set; }
void OnGroceryListChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// doing non-validation stuff
}
}
ビューを保持
<DataGrid
x:Name="MainGrid"
ItemsSource="{Binding GroceryList}"
SelectedItem="{Binding SelectedItem}"
...
>
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="TextBlock.ToolTip"
Value="{Binding Error}" />
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
...
<DataGridTextColumn Header="Item" Width="*" Binding="{Binding Name, ValidatesOnDataErrors=True}" IsReadOnly="false" />
</DataGrid.Columns>
</DataGrid>
GroceryItemにデフォルトのctorが必要なので、DataGridに自動的に行を追加させることはできません。コレクションをコントロールするメインのビューモデルにAddCommandが必要ですが、はい、これは明確な可能性に同意します。 – Berryl
あなたのアイデアはMVVMについて何も違反していません。私はおそらく、すべての通知がすでにデータバインディングから来ていると思っています。私が見ていないよりゆるやかに結合されたソリューションを利用できるかもしれません。 Cheers – Berryl
デフォルトでは、アイテムはコレクションのメンバーであることを実際には認識していません。コレクションへの参照を渡すことは、私が考えることができるアイテムからコレクションにアクセスするための最も邪魔な方法であり、私はそれを多く使用します。 – Paparazzi