DataGridViewComboBoxColumn не позволяет мне выбирать объект из списка

#c# #.net #datagridview

#c# #.net #datagridview

Вопрос:

У меня есть DataGridView, который позволяет пользователю добавлять новый объект в список. Одной из важных частей этого является выбор типа из определяемого пользователем списка.

Я определяю столбцы следующим образом:

 this.DataGridView.Columns.Add(new DataGridViewComboBoxColumn
                              {
                                  Name = "Resource",
                                  DataPropertyName = "Resource",
                                  DataSource = new BindingSource { DataSource = this.Document.Resources },
                                  ValueType = typeof(Resource),
                                  DisplayMember = "Name"
                              });
 

Затем я устанавливаю источник данных DataGridView в список пользовательских ресурсов:

 BindingList<UserResource> relatedResources = new BindingList<UserResource>(this.User.ResourcesRequired);
this.DataGridView.DataSource = relatedResources;
 

Макет класса ресурсов выглядит следующим образом:

 public class Resource
{
    public string Name { get; set; }
    public string Description { get; set; }
    public int InitialLevel { get; set; }
}
 

Класс UserResource выглядит следующим образом:

 public class UserResource
{
    public Resource Resource { get; set; }
    public int CurrentLevel { get; set;
}
 

Пользовательский класс выглядит следующим образом:

 public class User
{
    public string Name { get; set; }
    public IEnumerable<UserResource> Resources { get; set; }
}
 

Я вижу список доступных типов ресурсов, но элемент, выбранный в ячейке DataGridViewComboBox, не остается выбранным. После выбора элемента, когда я перехожу к следующему полю, ячейка DataGridViewComboBox очищается.

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

На случай, если людям интересно, я вообще не использую какой-либо объектно-реляционный картограф или какой-либо уровень базы данных. Все объекты в памяти записываются и считываются из XML-документа.

Я, честно говоря, не уверен, как продолжить отладку этой проблемы отсюда. У кого-нибудь есть какие-либо рекомендации?

Комментарии:

1. какова структура класса Resource и UserResource?

2. @Chiramisu: Если вы посмотрите на историю моих вопросов, вы увидите, что у меня есть привычка задавать вопросы, на которые очень сложно ответить, а в некоторых случаях, вероятно, невозможно ответить. У меня также есть несколько случаев, когда люди дали ответ в комментариях, поэтому я не могу пометить ответ как принятый. Я обещаю, что если вы сможете решить мой вопрос, я отмечу его как принятый.

3. @DeveloperX: я добавил структуру ресурсов, UserResource и пользовательских классов.

Ответ №1:

Хорошо, я внес некоторые изменения. Теперь сначала все работает нормально. Измените класс ресурсов на:

     public class Resource
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public int InitialLevel { get; set; }
//added by dx
        public new string ToString()
        {
            return Name;
        }
    }
 

Создайте новый класс для поля со списком Grid:

     public class  ComboSource
    {
        public string Name
        {
            get
            {
                if (SourceValue != null)
                    return SourceValue.ToString();
                return string.Empty;
            }
        }
        public Resource SourceValue{ get; set; }

    }
 

Пример использования:

        private List<ComboSource> resources = new List<ComboSource>();
            this.resources.Add(new ComboSource() { SourceValue = new Resource() { Name = "rs1", Description = "a"} });
            this.resources.Add(new ComboSource() { SourceValue = new Resource() { Name = "rs2", Description = "b" } });
            this.resources.Add(new ComboSource() { SourceValue = new Resource() { Name = "rs3", Description = "c" } });
 

и

         this.dataGridView1.Columns.Add(new DataGridViewComboBoxColumn
        {
            Name = "Resource",
            DataPropertyName = "Resource",
            ValueMember = "SourceValue",
            DataSource = new BindingSource { DataSource = this.resources },
            ValueType = typeof(Resource),
            DisplayMember = "Name"
        });
 

Комментарии:

1. Спасибо вам за это. Я пробовал что-то подобное ранее, и, похоже, это не сработало, но, похоже, есть проблема с самим элементом управления полем со списком. Я должен сделать что-то другое, чтобы заставить его работать. Я должен щелкнуть поле со списком, щелкнуть по нему еще раз, чтобы присвоить ему значение, щелкнуть по нему еще раз, чтобы создать меню, а затем я должен щелкнуть по элементу в меню, чтобы сохранить его значение. Затем он работает так, как ожидалось. Этот пример кода, который вы предоставили, определенно кому-нибудь когда-нибудь поможет. Теперь пользовательский интерфейс просто чрезвычайно раздражает.

2. Это сработало, но возникла другая проблема, связанная с пользовательским интерфейсом. Тем не менее, вы решили мою проблему. Пожалуйста, наслаждайтесь восхитительной репутацией с моими дополнениями.

3. Я объяснил в первом комментарии к вашему ответу. Я должен щелкнуть некоторые дополнительные элементы в поле со списком, чтобы он действительно выбрал элемент.

Ответ №2:

Я не думаю, что проблема связана с этим элементом управления. Вы можете выбрать элемент просто отлично. Как вы говорите, при перемещении по форме элемент очищается.

Это означает, что есть другой источник, который выполняет проверку этого элемента управления и решает его очистить. Пожалуйста, поищите другие части вашего кода или ссылки на событие изменения, которые могут изменять выбранное значение.

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

Комментарии:

1. На самом деле это действительно хорошая мысль, но ничто вообще не просматривает это представление datagrid или какую-либо из ячеек. По причинам, связанным с NDA, я не могу отправить вам исходный код формы, поэтому я собираюсь воспроизвести эту проблему в новом проекте и вставить ее в Pastebin. Спасибо за ваше время до сих пор!

Ответ №3:

                     <telerik:DataFormComboBoxField Grid.Row="0" Grid.Column="2" Label="Time Zone:" LabelPosition="Above">
                    <telerik:RadComboBox SelectedValue="{Binding TimeZoneID, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}" 
                                        ItemTemplate="{StaticResource DataTemplateTimeZone}" 
                                        SelectedValuePath="ID" 
                                        ItemsSource="{Binding DataSource.TimeZoneDataSource, Source={StaticResource vmProxy}}"
                                        IsEnabled="True"/>
                </telerik:DataFormComboBoxField>
 

Я бы рекомендовал использовать viewmodel, который содержит observablecollection, и использовать http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx

как я делаю со StaticResource vmProxy