2012-03-10 4 views
0

Я пытаюсь создать зависимость проверки между двумя столбцами datagrid.Как создать зависимость проверки datagrid между столбцами

Первый столбец - это выпадающее поле. (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; 
    } 
} 
+0

Какова цель управления ComboBox? Должна ли быть подтверждена его выбранная ценность?В вашем примере вы можете принудительно выполнить проверку, вызывая 'RuleWrapper = RuleWrapper', но я не уверен, что это то, что вам нужно. – vorrtex

+0

Выбор блока combox запускает другую проверку правилом. Поэтому, когда я делаю RuleWrapper = RuleWrapper, чтобы заставить проверку в коде позади, я получаю исключение ValidationException, но я не знаю, как его обрабатывать, поэтому он корректно отображается на datagrid. – Stainedart

+0

Я знаю, как принудительно проверять, если я использую IDataErrorInfo или Интерфейсы INotifyDataErrorInfo. Как вы думаете, если я полностью переписал эту проверку, чтобы она выполнялась этими интерфейсами? Затем вам придется переписать весь код проверки. – vorrtex

ответ

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 (() => ... с собственной реализацией (_prop = значение; RaisePropertyChanged ("строка «); и т.п..)

Обратите внимание, что повышение свойства измененного события на свойство только для чтения вызывает проверку будет происходить на ту собственность, которая является полезной

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

+0

В этой статье http://www.codeproject.com/Articles/30905/WPF-DataGrid-Practical-Examples#exception есть полезная информация о проверке DataGrid. Возможно, мне придется проверить мое утверждение о том, что ValidationException не работает. :) – Phil

+0

Спасибо, что ответите Филу. Я читаю ссылки, которые вы предоставили. – Stainedart

+0

Эй, Фил, я следил за вашими советами и продолжал и реализовал интерфейс INotifyDataErrorInfo, но у меня все еще есть проблемы, см. Http://stackoverflow.com/questions/9670118/inotifydataerrorinfo-not-raining-error-changed-in-code-behind – Stainedart

Смежные вопросы