MVVM WPF:验证自动生成列的datagrid行 [英] MVVM WPF : Validating datagrid row for autogeneratedcolumns
问题描述
我正在创建一个 DataTable
,其列存储在列表中。
I am creating a DataTable
whose columns are stored in a list.
public class CustomColumn
{
public string ColumnName { get; set; }
public int MinLength { get; set; }
public int MaxLength { get; set; }
}
public class ViewModel
{
public List<CustomColumn> Columns { get; set; }
public DataTable MyTable { get; set; }
public ViewModel()
{
InitializeCustomColumns();
MyTable = new DataTable();
foreach (CustomColumn column in Columns)
{
MyTable.Columns.Add(column.ColumnName, typeof(string));
}
}
}
现在我绑定 DataTable
到 DataGrid
,并允许用户在 DataGrid
。我的 DataGrid
列是在运行时初始化列列表时自动生成的。当用户在行的特定列中输入一些值时,我想根据 CustomColumn
属性 - > MinLength
(最小字符串长度)& MaxLength
(最大允许的字符串长度)。如果验证失败,我想显示DataGrid中显示的无效输入的默认红色边框。我正在追踪MVVM软件架构模式。
Now I am binding the DataTable
to a DataGrid
and allowing the user to add rows in the DataGrid
. My DataGrid
Columns are auto generated as the Column List is initialized at run time. When the user enter some value in particular column of the row, I want to validate based on CustomColumn
Properties -> MinLength
(Minimum string length) & MaxLength
(Maximum allowed string length). If the validation fails I want to show the default red border that appears in DataGrid for invalid input. I am following MVVM software architecture pattern.
编辑
c $ c> ColumnChanging 监听器
I attached ColumnChanging
Listener
MyTable.ColumnChanging += tableColumnChanging;
private void tableColumnChanging(object sender, DataColumnChangeEventArgs e)
{
//I am able to validate here using my logic
if(!isValid(e))
{
object badValue = e.ProposedValue;
e.ProposedValue = "Bad Data";
e.Row.RowError = "The column contains an error";
e.Row.SetColumnError(e.Column, "Column cannot be " + badValue);
}
else
{
...
}
}
我可以验证,但我想显示我的单元格!标记如果 isValid
返回false。
I am able to validate but I want to display my cell with ! mark if isValid
returns false.
推荐答案
我设法做了相同的解决方法
Well I managed to do a workaround for the same
xaml
<ScrollViewer xmlns:l="clr-namespace:CSharpWPF">
<ScrollViewer.Resources>
<DataTemplate DataType="{x:Type l:CustomTable}">
<DataTemplate.Resources>
<l:ErrorToVisibilityConverter x:Key="ErrorToVisibilityConverter" />
<Style TargetType="DataGridCell">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridCell">
<Grid Background="{TemplateBinding Background}">
<StackPanel Orientation="Horizontal">
<TextBlock Text=" ! "
FontWeight="Bold"
Foreground="Red">
<TextBlock.Visibility>
<MultiBinding Converter="{StaticResource ErrorToVisibilityConverter}"
Mode="OneWay">
<Binding RelativeSource="{RelativeSource FindAncestor,AncestorType=DataGridCell}" />
<Binding Path="Tag.Errors"
RelativeSource="{RelativeSource FindAncestor,AncestorType=DataGrid}" />
<Binding />
</MultiBinding>
</TextBlock.Visibility>
</TextBlock>
<ContentPresenter />
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataTemplate.Resources>
<StackPanel>
...
</StackPanel>
</DataTemplate>
</ScrollViewer.Resources>
<ContentControl Content="{Binding TableCollection}" />
</ScrollViewer>
我添加了一个 Style
for DataGridCell
并使用我们的额外元素定义了一个自定义模板
,以显示!
标记
I have added a Style
for DataGridCell
and defined a custom Template
with our extra element to display a !
mark
转换器类
namespace CSharpWPF
{
public class ErrorToVisibilityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
DataGridColumn column = values[0] as DataGridColumn;
ObservableCollection<DataColumnChangeEventArgs> errors = values[1] as ObservableCollection<DataColumnChangeEventArgs>;
DataRowView view = values[2] as DataRowView;
DataColumnChangeEventArgs args = errors.FirstOrDefault(e => (e.Row == view.Row) && (e.Column.Ordinal == column.DisplayIndex));
return view.Row.HasErrors && args != null ? Visibility.Visible : Visibility.Collapsed;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
这将检测是否当前单元格是受影响的,并返回 Visibility.Visible
如果为true否则 Visibility.Collapsed
因此隐藏或显示额外的元素取决于错误状态
this will detect if the current cell is the one which is affected and return the Visibility.Visible
if true otherwise Visibility.Collapsed
hence hiding or showing the extra element depending on the error state
更改 CustomTable
public CustomTable()
{
...
Errors = new ObservableCollection<DataColumnChangeEventArgs>();
}
private void tableColumnChanging(object sender, DataColumnChangeEventArgs e)
{
if (!isValid(e))
{
object badValue = e.ProposedValue;
e.ProposedValue = "Bad Data";
e.Row.RowError = "The column contains an error";
e.Row.SetColumnError(e.Column, "Column cannot be " + badValue);
Errors.Add(e);
OnPropertyChanged("Errors");
}
else
{
DataColumnChangeEventArgs args = Errors.FirstOrDefault(ee => (ee.Row == e.Row) && (ee.Column == e.Column));
if (args != null)
{
Errors.Remove(args);
OnPropertyChanged("Errors");
}
//...
}
}
public ObservableCollection<DataColumnChangeEventArgs> Errors { get; set; }
结果
所以整个想法是添加一个额外的属性与通知更改能力并将其用作触发器和其他属性来检测适当的列,而休息是我们额外的可见性!元素在自定义模板中
so the whole idea is to add an extra property with notification change capability and use it as a trigger and other property for detecting the appropriate column, and rest is the visibility of our extra ! element in the custom template
这篇关于MVVM WPF:验证自动生成列的datagrid行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!