Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.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# MVVM WPF:验证自动生成列的datagrid行_C#_Wpf_Mvvm_Datagrid - Fatal编程技术网

C# MVVM WPF:验证自动生成列的datagrid行

C# MVVM WPF:验证自动生成列的datagrid行,c#,wpf,mvvm,datagrid,C#,Wpf,Mvvm,Datagrid,我正在创建一个数据表,其列存储在列表中 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; se

我正在创建一个
数据表
,其列存储在列表中

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));
        }
    }
}

我可以验证,但我想显示我的手机!如果
是有效的,则标记
返回false。

我设法解决了同样的问题

xaml

这将检测当前单元格是否是受影响的单元格,并根据错误状态返回
可见性.Visible
如果为true,则返回
可见性.Collapsed
,从而隐藏或显示额外的元素

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; }
publiccustomtable()
{
...
错误=新的ObservableCollection();
}
私有void tableColumnChanging(对象发送方、DataColumnChangeEventArgs e)
{
如果(!isValid(e))
{
对象badValue=e.建议值;
e、 ProposedValue=“坏数据”;
e、 Row.RowError=“该列包含错误”;
e、 Row.SetColumnError(例如,Column,“Column不能是”+badValue);
添加(e);
OnPropertyChanged(“错误”);
}
其他的
{
DataColumnChangeEventArgs args args=Errors.FirstOrDefault(ee=>(ee.Row==e.Row)&&(ee.Column==e.Column));
如果(args!=null)
{
错误。删除(args);
OnPropertyChanged(“错误”);
}
//... 
}
}
公共ObservableCollection错误{get;set;}
结果


因此,整个想法是添加一个具有通知更改功能的额外属性,并将其用作触发器和其他属性来检测适当的列,而rest是我们额外属性的可见性!自定义模板中的元素

-1阿披实,你现在应该知道,这不是一个你可以来说这是我想要的,并期望其他用户为你做工作的网站。。。你需要做的工作,只是来这里问你是否被困在一个特定的部分。因此,我建议你去尝试满足你的要求,如果你陷入困境,那么你应该提供证据来证明你的问题。@Sheridan我知道我问了很多问题。但我只是在做了充分的研究之后才提出这个问题。我当前的WPF应用程序有点复杂,因此我在提问之前尝试简化问题,并提供我问题的简化示例。有些事情是我无法理解的。阿披实,这不是问很多问题。。。它是关于询问代码,而不显示您自己已经尝试过。由于您现在已经提供了相关代码,我现在将删除我的否决票,尽管您的代码仍然不完整,不会重现您的问题。我们遇到了一种情况。由于
DataRow
未实现
INotifyPropertyChanged
,因此设置
rowrerror
或任何其他属性不会传播到UI,因此我们无法直接执行任何触发。因此,想知道
DataTable
是必要的,还是我们也可以使用其他一些集合类?@pushpraj从DataTable转移到其他集合确实很困难:(
<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>
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();
        }
    }
}
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; }