Короткие и простые: поскольку элементы, которые вы ищете, не существуют в документе (пока).
В оставшуюся часть этого ответа я буду использовать getElementById
как пример, но то же самое относится к getElementsByTagName
, querySelector
и любому другому методу DOM, который выбирает элементы.
Возможные причины
Есть две причины, по которым элемент может не существовать:
getElementById
, действительно соответствует идентификатору существующего элемента в (сгенерированном) HTML и что у вас не было с ошибкой идентификатор (идентификаторы чувствительный !). Кстати, в большинстве современных браузеров , которые реализуют методы querySelector()
и querySelectorAll()
, нотация стиля CSS используется для извлечения элемента его id
, например: document.querySelector('#elementID')
, в отличие от способа, с помощью которого элемент извлекается его id
в [[16]; в первом символе #
необходимо, во втором это приведет к тому, что элемент не будет извлечен. getElementById
]. Последний случай довольно распространен. Браузеры анализируют и обрабатывают HTML сверху вниз. Это означает, что любой вызов элемента DOM, который встречается до появления этого элемента DOM в HTML, не будет выполнен.
Рассмотрим следующий пример:
Появляется div
после script
. В настоящий момент сценарий выполняется, элемент не существует , но и getElementById
вернут null
.
jQuery
То же самое относится к все селекторы с jQuery. jQuery не найдет элементов, если вы ошибочно написали ваш селектор, или вы пытаетесь выбрать их , прежде чем они на самом деле существуют .
Добавленный поворот - это когда jQuery не найден потому, что вы загрузили скрипт без протокола и запускаетесь из файловой системы:
этот синтаксис используется, чтобы позволить сценарию загружаться через HTTPS на странице с протоколом https: // и для загрузки HTTP-версии на странице с протоколом http: //
У этого есть неудачный побочный эффект попытки и невозможность загрузить file://somecdn.somewhere.com...
Решения
Прежде чем позвонить getElementById
(или любой метод DOM, если на то пошло), убедитесь, что элементы, к которым вы хотите получить доступ, существуют, т. е. загружается DOM.
Это может быть обеспечено просто добавив ваш JavaScript после к соответствующему элементу DOM
, и в этом случае вы также можете поместить код непосредственно перед тегом закрывающего тела (
) (все DOM элементы будут доступны в момент выполнения скрипта). [/ g3 6]
Другие решения включают прослушивание событий load
[MDN] или DOMContentLoaded
[MDN] . В этих случаях не имеет значения, где в документе вы помещаете код JavaScript, вам просто нужно запомнить, чтобы весь обработчик DOM обрабатывался в обработчиках событий.
Пример:
window.onload = function() {
// process DOM elements here
};
// or
// does not work IE 8 and below
document.addEventListener('DOMContentLoaded', function() {
// process DOM elements here
});
Более подробную информацию об обработке событий и различиях браузера см. в статьях на странице quirksmode.org .
jQuery
Сначала убедитесь, что jQuery загружен правильно , Используйте инструменты разработчика браузера , чтобы узнать, был ли найден файл jQuery и исправлен ли URL-адрес, если он не был (например, добавьте схему http:
или https:
в начале, отрегулируйте путь, и т. д.)
Прослушивание событий load
/ DOMContentLoaded
- это именно то, что делает jQuery с .ready()
[docs] . Весь ваш код jQuery, который влияет на элемент DOM, должен находиться внутри этого обработчика событий.
На самом деле в учебнике j8uery явно указано: Как почти все, что мы делаем при использовании jQuery, читает или манипулирует объектной моделью документа (DOM), мы должны убедиться, что мы начинаем добавлять события и т. д., как только DOM готов. Для этого мы регистрируем готовое событие для документа. В качестве альтернативы вы также можете использовать сокращенный синтаксис: Оба эквивалентны.
$(document).ready(function() {
// do stuff when DOM is ready
});
$(function() {
// do stuff when DOM is ready
});
Всякий раз, когда я это делаю, я обычно делаю grid.DataSource
результатом проекции LINQ на объекты.
Так что-то вроде этого:
grid.DataSource = objects.Select(o => new
{ Column1 = o.SomeValue, Column2 = o.SomeOtherValue }).ToList();
Приятно, что вы можете установить значение AutoGenerateColumns
в значение true, которое будет генерировать столбцы на основе свойств проецируемых объектов.
Edit:
Единственным недостатком этого подхода является то, что, проектируя все в анонимный объект могут возникнуть проблемы в ситуациях, когда вам нужно, например, получить доступ к определенному объекту в событии клика.
В этом случае вам может быть лучше определить явную модель представления и проецировать ваши объекты в них. Например,
class MyViewModel
{
public int Column1 { get;set; }
public int Column2 { get;set; }
}
grid.DataSource = objects.Select(o => new MyViewModel()
{ Column1 = o.SomeValue, Column2 = o.SomeOtherValue }).ToList();
Редактировать 2:
MyViewModel
представляет все столбцы, которые вы хотите отобразить в DataGridView
. Разумеется, свойства примера должны быть переименованы в соответствии с тем, что вы делаете. В общем, точка ViewModel должна служить своего рода преобразователем, который опосредует между моделью (в вашем случае ваш список объектов) и представлением.
Если вы хотите сохранить ссылку на базовый объект, лучший способ - предоставить его через конструктор:
class MyViewModel
{
public int Column1 { get;set; }
public int Column2 { get;set; }
....
private SomeType _obj;
public MyViewModel(SomeType obj)
{
_obj = obj;
}
public SomeType GetModel()
{
return _obj;
}
}
grid.DataSource = objects.Select(o => new MyViewModel(o)
{ Column1 = o.SomeValue, Column2 = o.SomeOtherValue }).ToList();
. Причина, по которой я пошел для метода getter для извлечения базового объекта модели, - это просто избежать создания столбца для это.
Это мой код из старого проекта. Он может работать для вашего дела.
OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM uyeler", baglanti);
da.Fill(dbDataSet1, "uyeler");
//Set AutoGenerateColumns False
dataGridView1.AutoGenerateColumns = false;
//Set Columns Count
dataGridView1.ColumnCount = 5;
//Add Columns
dataGridView1.Columns[0].Name = "İsim"; // name
dataGridView1.Columns[0].HeaderText = "İsim"; // header text
dataGridView1.Columns[0].DataPropertyName = "ad"; // field name
dataGridView1.Columns[1].HeaderText = "Soyisim";
dataGridView1.Columns[1].Name = "Soyisim";
dataGridView1.Columns[1].DataPropertyName = "soyad";
dataGridView1.Columns[2].Name = "Telefon";
dataGridView1.Columns[2].HeaderText = "Telefon";
dataGridView1.Columns[2].DataPropertyName = "telefon";
dataGridView1.Columns[3].Name = "Kayıt Tarihi";
dataGridView1.Columns[3].HeaderText = "Kayıt Tarihi";
dataGridView1.Columns[3].DataPropertyName = "kayit";
dataGridView1.Columns[4].Name = "Bitiş Tarihi";
dataGridView1.Columns[4].HeaderText = "Bitiş Tarihi";
dataGridView1.Columns[4].DataPropertyName = "bitis";
dataGridView1.DataSource = dbDataSet1;
dataGridView1.DataMember = "uyeler";
Вы можете использовать привязки данных с помощью AutoGenerateColumns = false
и используя DataPropertyName, как это
grid.Columns["Column_name_1"].DataPropertyName = "public_property_1";
grid.Columns["Column_name_2"].DataPropertyName = "public_property_2";
Таким образом, только связанные столбцы будут показаны в представлении datagridview, и вы можете создать столбцы в редакторе, если хотите , Открытые свойства могут быть любыми публичными атрибутами внутри вашего объекта.
Если вы редактируете свои данные из datagridview, вы должны использовать NotifyPropertyChanged в методах набора. Мой вопрос / ответ здесь , где я объясняю это до конца.
Вы также можете использовать Attribute [Browsable (false)] для любого свойства в базовых объектах, что может быть уместно. Это, конечно же, приведет к тому, что столбец не будет доступен для просмотра в другом месте, поэтому вы можете обнаружить, что это нежелательно.
:D
– spajce
10 February 2013 в 06:45
SqlCommand cmd6 = new SqlCommand("SELECT * FROM tblinv WHERE invno='" + textBox5.Text + "'",cn);
SqlDataReader sqlReader6 = cmd6.ExecuteReader();
if (sqlReader6.HasRows)
{
DataTable dt = new DataTable();
DataTable dt1 = new DataTable();
dt.Load(sqlReader6);
dt1 = dt.DefaultView.ToTable(true, "ChallanNo", "ProductName", "UoM", "Price", "Qty","Subtotal");
dataGridView2.DataSource = dt1;
}
Вы можете сделать что-то вроде этого.
Для отображения только столбцов цветности в DataGridView
сначала вы берете данные в DataTable
, как это.
String query="Your query to dispplay columns from the database";
SqlCommand cmd=new SqlCommand(query,con); //con is your Connection String
con.Open();
DataTable dt=new DataTable();
SqlDataAdapter da=new SqlDataAdapter(cmd);
da.Fill(dt); //Now this DataTable is having all the columns lets say
/* Now take another temporary DataTable to display only particular columns*/
DataTable tempDT=new DataTable();
tempDT=dt.DefaultView.ToTable(true,"Your column name","your column name");
//Now bind this to DataGridView
grid.DataSource=tempDT;
con.Close();
Я знаю, что это довольно длительный процесс. Те, кому нужно работать, могут не понравиться. : P
Но я думаю, что он отлично работает.