MVVM WPF:验证自动生成列的datagrid行 [英] MVVM WPF : Validating datagrid row for autogeneratedcolumns

查看:385
本文介绍了MVVM WPF:验证自动生成列的datagrid行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆