Miguel Peixoto
Top achievements
Rank 1
Miguel Peixoto
asked on 26 Nov 2010, 01:36 PM
Hi,
Hope someone can help me with this issue that I'm facing right now.
I'm trying to implement some behaviours in calculated columns (which are not Expression columns by the way). The goal is to have the last column value returned by the business layer based in the other column values.
I'm actually setting the DataContext as a DataView (DataTable.DefaultView), but when I try to programmatically make any change to the DataContext, the last column value doesn't actually refresh (visually) until I change to another row.
I thought that using DefaultView, and since it implements the INotifyPropertyChanged, the row being edited would be refreshed automatically. But in fact that doesn't happen in this case.
Converters and Expression columns are not exactly an option (at least I think so), since I send the grid's DataContext back to my Business layer where I set the last column value for each row.
Help would be extremely appreciated.
Hope someone can help me with this issue that I'm facing right now.
I'm trying to implement some behaviours in calculated columns (which are not Expression columns by the way). The goal is to have the last column value returned by the business layer based in the other column values.
I'm actually setting the DataContext as a DataView (DataTable.DefaultView), but when I try to programmatically make any change to the DataContext, the last column value doesn't actually refresh (visually) until I change to another row.
I thought that using DefaultView, and since it implements the INotifyPropertyChanged, the row being edited would be refreshed automatically. But in fact that doesn't happen in this case.
Converters and Expression columns are not exactly an option (at least I think so), since I send the grid's DataContext back to my Business layer where I set the last column value for each row.
Help would be extremely appreciated.
4 Answers, 1 is accepted
0
Hello Miguel Peixoto,
All the best,
Milan
the Telerik team
It would be really helpful if you could reveal additional details about your solution. How are the values of the calculated column generated?
All the best,
Milan
the Telerik team
Browse the videos here>> to help you get started with RadControls for WPF
0
Miguel Peixoto
Top achievements
Rank 1
answered on 02 Dec 2010, 01:37 PM
Hi Milan,
The problem was that while I was changing a certain column value, there's a special column that I want to be updated once I leave the cell edit mode. I found that using the DefaultView I couldn't get the radgrid UI to be updated.
Then I came out with this solution: creating my own table by inheriting DataTable and implementing INotifyPropertyChanged on my own DataRow. The grid's DataContext is now set to the MyTable instead of its DefaultView.
And in fact now I get the behavior I was looking for...except now I cannot insert new rows with the ShowInsertRow option !
Any ideas on how I can fix this ? I'm really trying to avoid creating a button or a context menu option for the user to be able to insert a new row...
Please let me know if you need some more details.
The problem was that while I was changing a certain column value, there's a special column that I want to be updated once I leave the cell edit mode. I found that using the DefaultView I couldn't get the radgrid UI to be updated.
Then I came out with this solution: creating my own table by inheriting DataTable and implementing INotifyPropertyChanged on my own DataRow. The grid's DataContext is now set to the MyTable instead of its DefaultView.
And in fact now I get the behavior I was looking for...except now I cannot insert new rows with the ShowInsertRow option !
Any ideas on how I can fix this ? I'm really trying to avoid creating a button or a context menu option for the user to be able to insert a new row...
Please let me know if you need some more details.
/// <summary>
/// Class containing a table data.
/// </summary>
public
class
MyTable : DataTable
{
/// <summary>
/// Determines whether the specified table is empty.
/// </summary>
/// <returns>
/// <c>true</c> if the specified table is empty; otherwise, <c>false</c>.
/// </returns>
public
bool
IsEmpty()
{
if
(
this
==
null
)
{
return
true
;
}
if
(
this
.Rows.Count > 0)
{
return
false
;
}
return
true
;
}
/// <summary>
/// Determines whether the specified obj is equal.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>
/// <c>true</c> if the specified obj is equal; otherwise, <c>false</c>.
/// </returns>
public
bool
IsEqual(
object
value)
{
PfrDataTable table = (PfrDataTable)value;
if
(table ==
null
)
{
return
false
;
}
if
(
this
.Rows.Count != table.Rows.Count)
{
return
false
;
}
for
(
int
r = 0; r <
this
.Rows.Count; r++)
{
for
(
int
c = 0; c <
this
.Columns.Count; c++)
{
if
(
this
.Rows[r][c] != table.Rows[r][c])
{
return
false
;
}
}
}
return
true
;
}
#endregion
#region Override methods
/// <summary>
/// Gets the type of the row.
/// </summary>
/// <returns></returns>
protected
override
Type GetRowType()
{
return
typeof
(MyTableRow);
}
/// <summary>
/// Creates a new row from an existing row.
/// </summary>
/// <param name="builder">A <see cref="T:System.Data.DataRowBuilder"/> object.</param>
/// <returns>
/// A <see cref="T:System.Data.DataRow"/> derived class.
/// </returns>
protected
override
DataRow NewRowFromBuilder(DataRowBuilder builder)
{
return
new
MyTableRow(builder);
}
#endregion
}
/// <summary>
/// Class containing a table row data.
/// </summary>
public
class
MyTableRow : DataRow, INotifyPropertyChanged
{
#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="MyTableRow"/> class.
/// </summary>
/// <param name="rb">The Row Builder.</param>
public
MyTableRow(DataRowBuilder rb) :
base
(rb)
{
this
.AddRowEventHandler();
}
#endregion
#region Handlers
/// <summary>
/// Adds the row event handler.
/// </summary>
public
void
AddRowEventHandler()
{
this
.Table.ColumnChanged +=
new
DataColumnChangeEventHandler(HandleColumnChanged);
}
#endregion
#region Private Methods
/// <summary>
/// Handles the column changed.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="System.Data.DataColumnChangeEventArgs"/> instance containing the event data.</param>
private
void
HandleColumnChanged(
object
sender, DataColumnChangeEventArgs e)
{
if
(e.Row ==
this
)
{
OnPropertyChanged(e.Column.ColumnName);
}
}
#endregion
#region INotifyPropertyChanged Members
/// <summary>
/// Occurs when a property value changes.
/// </summary>
public
event
PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Called when [property changed].
/// </summary>
/// <param name="propertyName">Name of the property.</param>
protected
void
OnPropertyChanged(
string
propertyName)
{
var ev = PropertyChanged;
if
(ev !=
null
)
{
ev(
this
,
new
PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
0
Hi Miguel Peixoto,
Greetings,
Milan
the Telerik team
You could try the following approach:
public
MainWindow()
{
InitializeComponent();
this
.Bind();
this
.radGridView.AddingNewDataItem +=
new
EventHandler<GridViewAddingNewEventArgs>(radGridView_AddingNewDataItem);
this
.radGridView.RowEditEnded +=
new
EventHandler<GridViewRowEditEndedEventArgs>(radGridView_RowEditEnded);
}
void
radGridView_RowEditEnded(
object
sender, GridViewRowEditEndedEventArgs e)
{
if
(e.EditOperationType == GridViewEditOperationType.Insert)
{
this
.myDataTable.Rows.Add(e.EditedItem
as
DataRow);
this
.radGridView.Rebind();
}
}
void
radGridView_AddingNewDataItem(
object
sender, GridViewAddingNewEventArgs e)
{
e.NewObject =
this
.myDataTable.NewRow();
}
AddingNewdataItem should be used since the grid does not know how to create a new DataRow. One the data is created you should used RowEditEnded event to commit the new data.
Greetings,
Milan
the Telerik team
Browse the videos here>> to help you get started with RadControls for WPF
0
Miguel Peixoto
Top achievements
Rank 1
answered on 16 Dec 2010, 11:21 AM
Hi Milan,
I've followed your approach and it worked great.
Thanks!
I've followed your approach and it worked great.
Thanks!