Hi all, it's a long story, I have to show data in a grid, I were forced to use a datatable to represent records, luckily the radgridview works like a charm with datatables.
When i add a record to the datatable I call Rebind to let the grid stay in sync. And that worked fine for months.
Now the customer wants that when a record is inserted the grid scroll to show the latest record inserted.
So i tried the scrollintoview with no success. Then i used the BringIndexIntoView that worked.
But after the call to BringIndexIntoView the following call to Rebind generate a NullReferenceException.
Also note that if I try to catch the exception and show a standard windows messagebox the messagebox too raise an exception. Seems like the call to BringIndexIntoView messed up the program.
To reproduce the error i created a project if that can help. Just copy into a new VS2010 WPF project named WpfApplication1 using telerik 2010 Q1 SP2 and framework 4.0.
When running click on reset datasource then click twice on add record.
//MainWindow.xaml.cs
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.Windows;
using
System.Windows.Controls;
using
System.Windows.Data;
using
System.Windows.Documents;
using
System.Windows.Input;
using
System.Windows.Media;
using
System.Windows.Media.Imaging;
using
System.Windows.Navigation;
using
System.Windows.Shapes;
using
System.Data;
namespace
WpfApplication1
{
public
partial
class
MainWindow : Window
{
SampleData sd;
public
MainWindow() {
InitializeComponent();
}
private
void
button1_Click(
object
sender, RoutedEventArgs e) {
BindToNewDS();
}
private
void
BindToNewDS() {
sd =
new
SampleData(50);
radGridView1.ItemsSource = sd.TheTable;
}
private
void
button2_Click(
object
sender, RoutedEventArgs e) {
int
idx = sd.CreateSampleRecord();
radGridView1.Rebind();
DataRow dr = (radGridView1.ItemsSource
as
DataTable).Rows
.Find(
new
Object[] { idx });
if
(radGridView1.Items.Contains(dr))
{
int
iof = radGridView1.Items.IndexOf(dr);
radGridView1.BringIndexIntoView(iof);
}
}
}
}
MainWindow.xaml
<
Window
x:Class
=
"WpfApplication1.MainWindow"
Title
=
"MainWindow"
Height
=
"350"
Width
=
"525"
xmlns:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
>
<
Grid
>
<
Grid.RowDefinitions
>
<
RowDefinition
Height
=
"45"
></
RowDefinition
>
<
RowDefinition
Height
=
"*"
></
RowDefinition
>
</
Grid.RowDefinitions
>
<
telerik:RadGridView
ShowInsertRow
=
"False"
CanUserInsertRows
=
"False"
RowHeight
=
"22"
SelectionMode
=
"Extended"
Grid.Row
=
"1"
Name
=
"radGridView1"
IsReadOnly
=
"True"
>
<
telerik:RadGridView.Columns
>
</
telerik:RadGridView.Columns
>
</
telerik:RadGridView
>
<
Button
Content
=
"Reset datasource"
Height
=
"29"
HorizontalAlignment
=
"Left"
Margin
=
"16,11,0,0"
Name
=
"button1"
VerticalAlignment
=
"Top"
Width
=
"94"
Click
=
"button1_Click"
/>
<
Button
Content
=
"Add record and scroll to"
Height
=
"30"
HorizontalAlignment
=
"Left"
Margin
=
"132,10,0,0"
Name
=
"button2"
VerticalAlignment
=
"Top"
Width
=
"144"
Click
=
"button2_Click"
/>
</
Grid
>
</
Window
>
//SampleData.cs
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Text;
using
System.ComponentModel;
using
System.Data;
namespace
WpfApplication1
{
class
SampleData
{
//define fixed columns
private
DataColumn[] fixedColumns =
new
DataColumn[] {
new
DataColumn(
"Equipment"
,
typeof
(
string
)),
new
DataColumn(
"Place Of Receipt"
,
typeof
(
string
)),
new
DataColumn(
"Port Of Load"
,
typeof
(
string
)),
new
DataColumn(
"Port Of Discharge"
,
typeof
(
string
)),
new
DataColumn(
"Delivery Place"
,
typeof
(
string
))
};
//define variable columns, only a random subset of these columns will be added to resulting table
private
DataColumn[] varColumns =
new
DataColumn[] {
new
DataColumn(
"Freight"
,
typeof
(
decimal
)),
new
DataColumn(
"Bunker"
,
typeof
(
decimal
)),
new
DataColumn(
"Peak season"
,
typeof
(
decimal
)),
new
DataColumn(
"Pickup costs"
,
typeof
(
decimal
)),
new
DataColumn(
"Delivery costs"
,
typeof
(
decimal
))
};
private
string
[][] sampleData =
new
string
[][] {
new
string
[] {
"Equipment"
,
"20 box"
,
"20 o.t."
,
"40 box"
,
"40 o.t."
,
"40 h.c."
},
new
string
[] {
"Place Of Receipt"
,
"Lyon"
,
"Tolouse"
,
"Torino"
,
"Milano"
,
"Verona"
,
"Madrid"
},
new
string
[] {
"Port Of Load"
,
"Marseille"
,
"Genova"
,
"La Spezia"
,
"Barcelona"
,
"Napoli"
},
new
string
[] {
"Port Of Discharge"
,
"New York"
,
"Montreal ramp"
,
"Norfolk"
,
"Miami"
,
"Savannah"
},
new
string
[] {
"Delivery Place"
,
"Atlanta"
,
"Jersey City, NJ"
,
"Edison, NJ"
,
"Oaks, PA"
,
"Taftsville, CT"
},
};
private
Random randGenerator =
new
Random();
private
int
LastID = 0;
public
SampleData(
int
initialRecordCount)
{
GenerateTableDefinition();
CreateSampleRecord();
for
(
int
i = 1; i < initialRecordCount; ++i)
CreateSampleRecord();
}
public
int
CreateSampleRecord()
{
var row = m_TheTable.NewRow();
LastID += randGenerator.Next(99)+1;
row[
"ID"
] = LastID;
m_TheTable.Rows.Add(row);
foreach
(DataColumn dc
in
m_TheTable.Columns)
{
string
[] sample;
int
randIdx;
sample = sampleData.FirstOrDefault(a => a[0].Equals(dc.ColumnName));
if
(sample !=
null
)
{
randIdx = randGenerator.Next(sample.Count() - 2);
row[dc] = sample[randIdx + 1];
}
if
(dc.DataType ==
typeof
(
decimal
))
{
row[dc] = (
decimal
)(randGenerator.Next(60) * 50);
}
}
return
LastID;
}
private
void
GenerateTableDefinition()
{
//creating table
DataTable dt =
new
DataTable(
"FreightRates"
);
//creating primary key
dt.Columns.Add(
new
DataColumn(
"ID"
,
typeof
(
int
)));
//adding fixed columns to table
foreach
(DataColumn dc
in
fixedColumns)
{
dt.Columns.Add(dc);
}
//selecting randomly a number of variable columns to be added to the table
List<DataColumn> varColumnList = varColumns.ToList();
int
numberOfVariableColumns = randGenerator.Next(varColumnList.Count() - 1);
for
(
int
i = 0; i < numberOfVariableColumns; ++i)
{
int
randomlySelectedColumn = randGenerator.Next(varColumnList.Count() - 1);
dt.Columns.Add(varColumnList[i]);
varColumnList.RemoveAt(i);
}
//expliciting primary key
dt.PrimaryKey =
new
DataColumn[] { dt.Columns[
"ID"
] };
TheTable = dt;
}
private
DataTable m_TheTable;
public
DataTable TheTable
{
get
{
return
this
.m_TheTable; }
private
set
{
if
(value !=
this
.m_TheTable)
{
this
.m_TheTable = value;
}
}
}
}
}