Неожиданная красная граница (ошибка проверки) в DataGrid при выборе пустой строки - PullRequest
20 голосов
/ 08 октября 2011

Когда я выбираю (щелкая или с помощью клавиатуры) пустую строку в моей DataGrid (когда я хочу добавить новую строку), возникает непредвиденная ошибка проверки (но без исключения) - граница сетки данных меняется на красный цвет, так как выможно увидеть на изображении ниже.Когда я нажимаю второй раз на пустой строке, красная рамка исчезает.Все остальное работает нормально, добавлен новый ряд.Кроме того, у меня нет никаких правил проверки.И когда я создаю строку с пустым текстом, значение допустимо.

Мне не нужно это поведение и эту красную рамку, кто-нибудь знает, почему это происходит и как это исправить?Почему и где происходит сбой проверки?

enter image description here

Ниже я добавляю некоторый исходный код:

Определение DataGrid в xaml:

    <DataGrid IsSynchronizedWithCurrentItem="True" DisplayMemberPath="Name" 
 ItemsSource="{Binding Path=ConfigFiles}" SelectedItem="{Binding Path=SelectedConfigFile}" 
              Grid.Column="1" Height="87" Margin="0,26,11,32" Style="{DynamicResource DataGridStyle}">
        <DataGrid.Columns>
            <DataGridTextColumn Width="1*" Binding="{Binding Name}" />
        </DataGrid.Columns>
    </DataGrid>

MyЧасть ViewModel:

public class ManageModulesVM : BaseVM  // Implements INotifyPropertyChanged
{
    // ...

    public ObservableCollection<ConfigFile> ConfigFiles
    {
        get { return selectedModule == null ? null : selectedModule.ConfigFiles; }
        set
        {
            selectedModule.ConfigFiles = value;
            OnPropertyChanged(() => ConfigFiles);
        }
    }

    public ConfigFile SelectedConfigFile
    {
        get { return selectedModule == null ? null : selectedModule.SelectedConfigFile; }
        set
        {
            if (value != null)
            {
                selectedModule.SelectedConfigFile = value;
            }
            OnPropertyChanged(() => SelectedConfigFile);
            OnPropertyChanged(() => Parameters);
        }
    }

    // ...
}

Класс ConfigFile:

public class ConfigFile
{
    public string Name { get; set; }
    public IList<Parameter> Parameters { get; set; }

    public ConfigFile() { Name = ""; Parameters = new List<Parameter>(); }
}

Редактировать: После дальнейшего изучения я знаю, что привязка SelectedItem вызывает проблемы (когда я удаляю эту привязку, ошибка проверки перестает появляться), но я до сих пор не знаю, почему и как это исправить.

Ответы [ 5 ]

21 голосов
/ 09 октября 2011

Я нашел свое решение этого вопроса. Я написал конвертер значений и привязал его к привязке:

(SelectedItem="{Binding Path=SelectedConfigFile,Converter={StaticResource configFileConverter}}")

Преобразователь класса:

namespace Converters
{
    public class SelectedConfigFileConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if(value is ConfigFile)
                return value;
            return null;
        }
    }
}

Определить ресурс в resources.xaml файле (или в любом другом месте ресурсов):

<ResourceDictionary (...) xmlns:conv="clr-namespace:Converters" >
    <conv:SelectedConfigFileConverter x:Key="configFileConverter" />
</ResourceDictionary>

Преимущество этого решения состоит в том, что тип свойства SelectedConfigFile не изменился (к общему типу object), поэтому он все еще строго типизирован.

8 голосов
/ 08 октября 2011

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

Да, проблема связана с приведением типа.Вам необходимо изменить тип SelectedItem на тип объекта, как показано ниже.

public class ManageModulesVM : BaseVM  // Implements INotifyPropertyChanged
{
    // ...

    public object SelectedConfigFile
    {
        get { return selectedModule == null ? null : selectedModule.SelectedConfigFile; }
        set
        {
            if (value != null)
            {
                selectedModule.SelectedConfigFile = value;
            }
            OnPropertyChanged(() => SelectedConfigFile);
            OnPropertyChanged(() => Parameters);
        }
    }

    // ...
}
6 голосов
/ 07 марта 2016

Вот конвертер общего назначения, который вы можете использовать для любой DataGrid, привязывая любой тип элемента:

    public class DataGridItemConverter : MarkupExtension, IValueConverter
    {
    static DataGridItemConverter converter;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
        return value;
        }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
        return (value != null && value.GetType() == targetType) ? value : null;
        }

    public override object ProvideValue(IServiceProvider serviceProvider)
        {
        if (converter == null)
            converter = new DataGridItemConverter();
        return converter;
        }
    }

Поскольку он реализует MarkupExtension, вам даже не нужно определять статический ресурс, вы можете простоссылаться на это так:

SelectedItem="{Binding SelectedThing,Converter={conv:DataGridItemConverter}}"
3 голосов
/ 18 марта 2015

Вы можете просто добавить эту строку в свою DataGrid:

<DataGrid  Validation.ErrorTemplate="{x:Null}" />
0 голосов
/ 12 октября 2016

Вы можете просто добавить эту строку в свою DataGrid:

<DataGrid  Validation.ErrorTemplate="{x:Null}" />

Это решит проблему

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