Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在列之间创建datagrid验证依赖关系_C#_Silverlight_Validation_Xaml_Code Behind - Fatal编程技术网

C# 如何在列之间创建datagrid验证依赖关系

C# 如何在列之间创建datagrid验证依赖关系,c#,silverlight,validation,xaml,code-behind,C#,Silverlight,Validation,Xaml,Code Behind,我试图在两个datagrid列之间创建一个验证依赖项 第一列是一个下拉框。(DataGridTemplateColumn) 第二个是文本列。(DataGridTextColumn) 我试图从代码隐藏中的下拉框事件强制验证同一行的datagrid文本列单元格 谢谢你的帮助 <data:DataGridTemplateColumn Header="Type" > <data:DataGridTemplateColumn.Cel

我试图在两个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;
    }
}
公共字符串规则包装器
{
得到
{
返回此。规则;
}
设置
{
//必需的
if(value==null | | value==string.Empty)
{
抛出新的ValidationException(“需要规则”);
}
//如果类型为通道,则匹配正则表达式
Regex Regex=newregex(@“^(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-4]|[0-9]?)\(51[01]| 50[0-9]|[0-9]|[0-9]|[0-9]|[0-9]?)\)\)\”;
如果(类型==“通道”&&!注册表项匹配(值))
抛出新的ValidationException(“通道与正确的格式不匹配”);
//如果类型为trunk,则匹配范围
int值=-1;
//如果是数字,则匹配
if(int.TryParse(value,out intValue))
{
//如果数字在范围内,则匹配
如果(intValue<0 | | intValue>134217727)
抛出新的ValidationException(“主干值必须介于0和134317727之间”);
}
其他的
抛出新的ValidationException(“Trunk值必须是整数”);
这个规则=值;
}
}
需要注意的几件事(我仍在学习验证,所以我需要更正)

  • WPF不支持ValidationException

  • 在绑定中设置ValidatesOnExceptions=True只处理 内部使用的默认转换器中的异常(如将字符串转换为 数字)

  • 您自己的转换器中的异常不会被捕获并导致应用程序崩溃 崩溃

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

我现在也是从WPF的角度回答的。稍后我将在Silverlight上进行测试

MSDN在这里有一篇非常好的文章

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

<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,因此请使用您自己的实现(_prop=value;RaisePropertyChanged(“string”);等)替换我对Set(()=>…的使用

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

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
}
公共类DataGridValidationViewModels
{
公共DataGridValidationViewModels()
{
Items=新的ObservableCollection
{
新的DataGridValidationViewModel(),
新的DataGridValidationViewModel(),
新的DataGridValidationViewModel(),
新的DataGridValidationViewModel(),
新的DataGridValidationViewModel(),
新的DataGridValidationViewModel(),
新的DataGridValidationViewModel(),
};
}
公共IEnumerable项{get;set;}
}
公共类DataGridValidationViewModel:ViewModelBase,IDataErrorInfo
{
公共DataGridValidationViewModel()
{
_column1=“column1”;
_column2=“Column 2”;
}
私有字符串_column1;
公共字符串列1
{
获取{return\u column1;}
设置
{
设置(()=>Column1,ref _Column1,value);
第2列=数值;
}
}
私有字符串_column2;
公共字符串列2
{
获取{return\u column2;}
私有集{set(()=>Column2,ref_Column2,value);}
}
#IDataErrorInfo的区域实施
公共字符串此[string columnName]
{
得到
{
开关(列名称)
{
案例“第1栏”:
return Column1==“Error”?“Column1中有错误!”:string.Empty;
案例“第2栏”:
return Column1==“Error”?“第2列有错误!”:string.Empty;
}
返回字符串。空;
}
}
公共字符串错误
{
获取{return string.Empty;}
}
#端区
}
当您将第1列的文本更改为“错误”时,您会得到:


组合框控件的用途是什么?是否也要验证其所选值?在您的示例中,您可以通过调用
RuleWrapper=RuleWrapper
强制验证,但我不确定这是否是您需要的。组合框选择会触发对规则的不同验证。因此,当我执行RuleWrapper=RuleWrapper时,将强制验证代码背后的验证我抛出了一个ValidationException,但我不知道如何处理它,以便它在DataGrid上正确显示。如果我使用IDataErrorInfo或INotifyDataErrorInfo接口,我知道如何强制验证。如果我完全重写此验证,使其由这些接口执行,您认为如何你必须重写所有的验证代码。你不应该在一个属性集中有所有的逻辑!它是实际属性的包装器。你是说我应该为每个字段创建一个验证方法而不是使用setter吗?这篇文章有一些关于DataGrid验证的有用信息。我可能必须检查我的断言ValidationE例外不起作用