Ошибка проверки WPG DataGrid? - PullRequest
       0

Ошибка проверки WPG DataGrid?

8 голосов
/ 17 февраля 2011

Это может быть предполагаемая функциональность, но она мне кажется ошибкой.

Я использую готовую WPF DataGrid, привязанную к ObservableCollection и пытающуюся использовать некоторые правила проверки, чтобы обеспечить хорошую обратную связь с пользователем.Само собой разумеется, есть больше проблем, чем я могу сосчитать, но я остановлюсь на немедленном.

Вот краткое изложение проблемы:

  1. Привязать ItemsSource свойство кObservableCollection<T>
  2. Заполнить коллекцию
  3. Редактировать элемент в сетке таким образом, что это приведет к ошибке проверки
  4. Программно удалить этот элемент из ObservableCollection<T>

Когда эти шаги выполнены, GridView правильно распознает, что элемент был удален из коллекции, и удаляет строку из сетки.Тем не менее, Сетка теперь застряла в недопустимом состоянии, и никакие дальнейшие действия не могут быть выполнены с помощью пользовательского интерфейса на Сетка!

Опять же, для меня это очень большая ошибкавозможность программно удалять предметы из коллекции - это большое дело.

Кто-нибудь сталкивался с этим?Любые предложения о том, как обойти это?

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

Ваш объект реализует INotifyPropertyChanged? ДА

Это пользовательская коллекция? Нет старого простого ObservableCollection<T>

Как вы удаляете элементы из своей коллекции?

//Find any newly added item and remove it  
var someObject = SomeObjects
             .Where(obj => obj.SomeProperty == SomeValue)
             .First();

SomeObjects.Remove(someObject );

Как вы связываете свое правило проверки?

<DataGridTextColumn Header="SomeProperty">
    <DataGridTextColumn.Binding>
        <Binding Path="SomeProperty">
            <Binding.ValidationRules>
                <val:RequiredValidator ValidationStep="ConvertedProposedValue" 
                     ValidatesOnTargetUpdated="True" />
            </Binding.ValidationRules>
        </Binding>
    </DataGridTextColumn.Binding>
</DataGridTextColumn>

Как выглядит ваше правило проверки?

public class RequiredValidator : ValidationRule
{
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        if (value == null || String.IsNullOrWhiteSpace(value as String))
            return new ValidationResult(false, "Field is required!");

        return ValidationResult.ValidResult;
    }
}

Ответы [ 3 ]

1 голос
/ 24 января 2012

У меня была такая же проблема, и после долгого поиска я нашел решение:

Вы можете создать класс, производный от DataGrid. Там вы можете получить доступ к частной собственности с помощью отражения. Если вы сейчас удалите недопустимый элемент, вы можете вызвать функцию SetGridWritable (), а другие значения снова будут доступны для редактирования.

public class MyDataGrid : DataGrid
{
    public void SetGridWritable()
    {
        BindingFlags bindingFlags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Instance;
        PropertyInfo cellErrorInfo = this.GetType().BaseType.GetProperty("HasCellValidationError", bindingFlags);
        PropertyInfo rowErrorInfo = this.GetType().BaseType.GetProperty("HasRowValidationError", bindingFlags);
        cellErrorInfo.SetValue(this, false, null);
        rowErrorInfo.SetValue(this, false, null);
    }
}
1 голос
/ 24 июля 2014

Я провел несколько часов, пытаясь выяснить, что происходит.Наконец, простое обновление на Предметы решило проблему.Надеюсь, это поможет.

YourDataGrid.Items.Refresh();
0 голосов
/ 03 апреля 2011

У меня есть решение без решения, если вы заинтересованы:

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

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

т.е:

DataTrigger errorTrigger = CreateTrigger(CreateDirectBinding(property,new HasErrorValueConverter()), CreateErrorSetter(property));

Это решает проблемы, связанные с ошибками проверки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...