Как создать зависимость проверки сетки данных между столбцами - PullRequest
0 голосов
/ 10 марта 2012

Я пытаюсь создать зависимость проверки между 2 столбцами таблицы данных.

Первый столбец представляет собой раскрывающийся список.(DataGridTemplateColumn) Второй является текстовым столбцом.(DataGridTextColumn)

Я пытаюсь из события выпадающего списка в коде выполнить принудительную проверку ячейки текстового столбца таблицы данных той же строки.

Спасибо за вашу помощь.

            <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 Ответ

2 голосов
/ 11 марта 2012

Несколько вещей, на которые следует обратить внимание (я все еще учусь о проверке, поэтому я буду исправлен).

  • WPF не поддерживает ValidationException .

  • Установка ValidatesOnExceptions = True в привязках обрабатывает только исключения в используемых по умолчанию преобразователях по умолчанию (например, преобразование строки в число).

  • Исключения в ваших собственных конвертерах не фиксируются и вызывают ваше приложение врезаться.

  • Проверка выполняется с использованием IDataErrorInfo , INotifyDataErrorInfo (Silverlight и WPF 4.5) и ValidationRule

Также я отвечаю с точки зрения 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, поэтому замените использование Set (() => ... на вашу собственную реализацию (_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

...