Thanks,
Terry
6 Answers, 1 is accepted
Here's a slightly simplified version of my class:
public sealed class GridViewTimeLengthColumn : GridViewBoundColumnBase
{
public bool TimeUnitEnabled { get; set; }
public override string UniqueName
{
get { return base.UniqueName; }
set
{
base.UniqueName = value;
DataMemberBinding.Path =
new PropertyPath(value + "Summary"); // for sort/filter/group
}
}
public GridViewTimeLengthColumn()
{
TimeUnitEnabled =
true;
}
public override FrameworkElement CreateCellElement(GridViewCell cell, object dataItem)
{
return new TextBlock().SetOneWayBinding(TextBlock.TextProperty, UniqueName + "Summary");
}
public override FrameworkElement CreateCellEditElement(GridViewCell cell, object dataItem)
{
var grid = new Grid();
grid.ColumnDefinitions.Add(
new ColumnDefinition());
grid.ColumnDefinitions.Add(
new ColumnDefinition() { Width = GridLength.Auto });
var textBox = new TextBox().SetTwoWayBinding(TextBox.TextProperty, UniqueName);
grid.Children.Add(textBox);
var comboBox = new RadComboBox()
.SetOneWayBinding(
RadComboBox.ItemsSourceProperty, UniqueName + "TimeUnitItemsSource")
.SetTwoWayBinding(
RadComboBox.SelectedItemProperty, UniqueName + "TimeUnit");
Grid.SetColumn(comboBox, 1);
comboBox.IsEnabled = TimeUnitEnabled;
grid.Children.Add(comboBox);
return grid;
}
}
The 'SetOneWayBinding' and 'SetTwoWayBinding' methods are just extension methods that establish the bindings and set validation-related binding properties to 'true', all in one convenient call. As we're quickly approaching a deadline, any timely help you could provide on this would be greatly appreciated.
Thanks,
Terry
Generally, you may skip setting the validation-related properties of the binding. As once you set them, the Framework will perform the validation. What you may try to do is to handle the CellValidating event of the grid and perform the logic there.
Maya
the Telerik team
I don't think I'm understanding. I definitely don't want to handle the CellValidating event of the grid as I'm dong everything MVVM-style. That is why I'm setting the NotifyOnValidationError and ValidatesOnExceptions properties of the bindings to true. I'm not sure why you say I can generally skip setting these, as validation through the binding of my view model's properties would no longer work.
Ultimately, I just need to know exactly what prevents the cell from ending editing when one of the bindings has a validation error (as managed through the INotifyDataErrorInfo interface implemented by the view model) so I can do the same for this custom column.
Thanks,
Terry
Basically, for the time being the way to go is to handle the CellValidated event and perform the validation logic there. If you do not want to write any code in your code-behind, you might try to create a custom attached behavior and define it for the RadGridView.
On the other hand, we will do consider adding a method allowing the implementation of custom validation logic. However, I cannot specify any time frame for including such a feature.
Maya
the Telerik team
I have a custom cell created in CreateCellEditElement() that is a grid with a textBox and a comboBox. I added the binding and a converter to it. The controls work fine but when I edit the textBox, it fires CellValidating event and there the new value in e.NewValue member is coming as null instead of the edited value.
private
void
_grid_CellValidating(
object
sender, GridViewCellValidatingEventArgs e)
{
List<
object
> values = e.Row.Item
as
List<
object
>;
if
(values !=
null
)
{
int
index = e.Row.Cells.IndexOf(e.Cell);
ScenarioValue value = values[index]
as
ScenarioValue;
if
(value !=
null
)
{
string
errorDescription =
""
;
e.IsValid = value.IsValid(e.NewValue
as
string
,
out
errorDescription);
e.ErrorMessage = errorDescription;
e.Handled =
true
;
}
else
{
Parameter parameter = values[index]
as
Parameter;
if
(parameter !=
null
)
{
string
errorDescription =
""
;
e.IsValid = parameter.IsValid(e.NewValue
as
string
,
out
errorDescription);
e.ErrorMessage = errorDescription;
e.Handled =
true
;
}
}
}
}
public
override
FrameworkElement CreateCellEditElement(GridViewCell cell,
object
dataItem)
{
List<
object
> row = dataItem
as
List<
object
>;
if
(parameter.ParameterType == ParameterType.Time)
{
var grid =
new
Grid();
grid.ColumnDefinitions.Add(
new
ColumnDefinition());
grid.ColumnDefinitions.Add(
new
ColumnDefinition() { Width = GridLength.Auto });
Binding gridBinding =
new
Binding(DataMemberBinding.Path.Path);
gridBinding.Mode = BindingMode.TwoWay;
gridBinding.NotifyOnValidationError =
true
;
gridBinding.ValidatesOnExceptions =
true
;
gridBinding.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
gridBinding.Converter =
new
TimeAndUnitConverter(TimeAndUnitConverter.DataPortion.Time);
grid.SetBinding(TextBox.TextProperty, gridBinding);
var textBox =
new
TextBox();
Binding bindingTextBox =
new
Binding(DataMemberBinding.Path.Path);
bindingTextBox.Mode = BindingMode.TwoWay;
bindingTextBox.NotifyOnValidationError =
true
;
bindingTextBox.ValidatesOnExceptions =
true
;
bindingTextBox.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
bindingTextBox.Converter =
new
TimeAndUnitConverter(TimeAndUnitConverter.DataPortion.Time);
textBox.SetBinding(TextBox.TextProperty, bindingTextBox);
textBox.Height = 22;
grid.Children.Add(textBox);
var comboBox =
new
RadComboBox();
comboBox.ItemsSource = Parameter.TimeUnits;
Binding bindingCombo =
new
Binding(DataMemberBinding.Path.Path);
bindingCombo.Mode = BindingMode.TwoWay;
bindingCombo.NotifyOnValidationError =
true
;
bindingCombo.ValidatesOnExceptions =
true
;
bindingCombo.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
bindingCombo.Converter =
new
TimeAndUnitConverter(TimeAndUnitConverter.DataPortion.Unit);
comboBox.SetBinding(RadComboBox.SelectedItemProperty, bindingCombo);
Grid.SetColumn(comboBox, 1);
comboBox.IsEnabled =
true
;
grid.Children.Add(comboBox);
return
grid;
}
else
{
return
base
.CreateCellEditElement(cell, dataItem);
}
}
This would be the expected behavior since you predefine the editing element of the cell. What you may try is to override the GetNewValueFromEditor(object editor) method in the column definition and return the value you want. Another possible approach would be to find the TextBox/ RadComboBox from the EditingElement property of the arguments of the CellValidating event and get their values.
Maya
the Telerik team
Thank you for being the most amazing .NET community! Your unfailing support is what helps us charge forward! We'd appreciate your vote for Telerik in this year's DevProConnections Awards. We are competing in mind-blowing 20 categories and every vote counts! VOTE for Telerik NOW >>