如何在列之间创建datagrid验证依赖项

时间:2012-03-10 15:21:48

标签: c# silverlight validation xaml code-behind

我正在尝试在2个datagrid列之间创建验证依赖项。

第一列是下拉框。 (DataGridTemplateColumn) 第二个是文本列。 (DataGridTextColumn)

我正在尝试从后面的代码中的下拉框事件强制验证同一行的datagrid文本列单元格。

感谢您的帮助。

            <data:DataGridTemplateColumn Header="Type" >
                <data:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding Source={StaticResource TypeListContainer}, Path=TypeLists}" Loaded="TypeBoxLoaded" DropDownClosed="TypeBoxChanged">
                        </ComboBox>
                    </DataTemplate>
                </data:DataGridTemplateColumn.CellTemplate>
            </data:DataGridTemplateColumn>
            <data:DataGridTextColumn Header="Rule" Binding="{Binding RuleWrapper, ValidatesOnDataErrors=True, NotifyOnValidationError=True}" x:Name="RuleCol" />

这是属性

public string RuleWrapper
{
    get
    {
        return this.Rule;
    }
    set
    {
        //Required
        if (value == null || value == string.Empty)
        {
            throw new ValidationException("Rule is required");
        }
        //Match regular expression if type is channel
        Regex reg = new Regex(@"^(51[01]|50[0-9]|[0-4]?[0-9][0-9]?)\.(51[01]|50[0-9]|[0-4]?[0-9][0-9]?)\.(51[01]|50[0-9]|[0-4]?[0-9][0-9]?)\.(51[01]|50[0-9]|[0-4]?[0-9][0-9]?)$");
        if (Type == "channel" && !reg.IsMatch(value))
            throw new ValidationException("Channel not matching the right format");

        //Match range if type is trunk
        int intValue = -1;
        //Match if is a number
        if (int.TryParse(value, out intValue))
        {
            //Match if number is in the range
            if (intValue < 0 || intValue > 134217727)
                throw new ValidationException("Trunk value must be between 0 and 134317727");
        }
        else
            throw new ValidationException("Trunk value must a an integer");
        this.Rule = value;
    }
}

1 个答案:

答案 0 :(得分:2)

有几点需要注意(我还在学习验证,所以我有待纠正)。

  • WPF不支持 ValidationException

  • 在仅绑定句柄中设置 ValidatesOnExceptions = True 内部使用的默认转换器中的异常(例如将字符串转换为 数)。

  • 您自己的转换器中的异常未被捕获并导致您的应用    坠毁。

  • 使用 IDataErrorInfo INotifyDataErrorInfo(Silverlight和WPF 4.5) ValidationRule

    处理验证

此刻我正在回答WPF的观点。我稍后会测试Silverlight。

MSDN在这里有一篇非常好的文章关于binding and validation

这是我的示例,它演示了两个文本列之间的验证依赖关系(为简单起见)。第二列是只读的,但显示由第一列引起的验证错误。

<Grid>
    <Grid.DataContext>
        <Samples:DataGridValidationViewModels/>
    </Grid.DataContext>

    <DataGrid AutoGenerateColumns="False" ItemsSource={Binding Items}>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Column 1" Binding="{Binding Column1, ValidatesOnDataErrors=True}" />
            <DataGridTextColumn IsReadOnly="True" Header="Column 2" Binding="{Binding Column2, ValidatesOnDataErrors=True}" />
        </DataGrid.Columns>
    </DataGrid>
</Grid>

我正在使用MVVM Light作为我的视图模型/ INotifyPropertyChange支持,因此将 Set(()=&gt; ... 的使用替换为您自己的实现(_prop = value; RaisePropertyChanged( “string”);等)。

请注意,在只读属性上引发属性更改事件会导致在该属性上进行验证,这是有用的。

public class DataGridValidationViewModels
{
    public DataGridValidationViewModels()
    {
        Items = new ObservableCollection<DataGridValidationViewModel>
                    {
                        new DataGridValidationViewModel(),
                        new DataGridValidationViewModel(),
                        new DataGridValidationViewModel(),
                        new DataGridValidationViewModel(),
                        new DataGridValidationViewModel(),
                        new DataGridValidationViewModel(),
                        new DataGridValidationViewModel(),
                    };

    }

    public IEnumerable<DataGridValidationViewModel> Items { get; set; }
}

public class DataGridValidationViewModel : ViewModelBase, IDataErrorInfo
{
    public DataGridValidationViewModel()
    {
        _column1 = "Column 1";
        _column2 = "Column 2";
    }

    private string _column1;

    public string Column1
    {
        get { return _column1; }
        set
        {
            Set(() => Column1, ref _column1, value);
            Column2 = value;
        }
    }

    private string _column2;

    public string Column2
    {
        get { return _column2; }
        private set{ Set(()=>Column2, ref _column2, value);}
    }

    #region Implementation of IDataErrorInfo

    public string this[string columnName]
    {
        get
        {
            switch (columnName)
            {
                case "Column1":
                    return Column1 == "Error" ? "There's an error in column 1!" : string.Empty;

                case "Column2":
                    return Column1 == "Error" ? "There's an error in column 2!" : string.Empty;
            }

            return string.Empty;
        }
    }

    public string Error
    {
        get { return string.Empty; }
    }

    #endregion
}

当您将第1列的文本更改为“错误”时,您会得到:

enter image description here