0
votes

Please let me know if there's something wrong with my approach. I have a WPF window which contains a datagrid. This is for the users to input a list of object IDs for the program to process.

I am binding the ItemsSource of the DataGrid to an ObservableCollection, where MyObject is a class with a single string property - ObjectId.

I have an event for when collection is changed:

 void TasksList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            ProgressBarMax = TasksList.Count;
            TaskCountLabel = string.Format("{0} tasks to modify", TasksList.Count);
        }

I would also like to validate the data on input - the user might provide an incorrect Id, in which case I don't want to add it to the collection. However, when I access the e.NewItems[0] object, its ObjectId property is still null, so I cannot validate.

What is wrong with my approach?

Adding datagrid XAML as per comments:

<DataGrid Margin="5,0,5,10"
                                         ColumnWidth="*"
                                         ItemsSource="{Binding ElementName=ThisUc,
                                                               Path=TasksList,
                                                               Mode=TwoWay,
                                                               UpdateSourceTrigger=PropertyChanged}"
                                         Style="{x:Null}"
                                         CanUserAddRows="True" CanUserPasteToNewRows="True"
                                         x:Name="TasksDataGrid"
                                         CanUserDeleteRows="True"
                                         VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
                                         SelectionUnit="Cell" />
1
Perhaps you need to perform this validation before it is added to the collection instead of after. How are you currently adding items to this collection? An ICommand? - Mike Eason
@MikeEason - No... the collection is bound to the datagrid, so it gets updated when a user starts typing in the datagrid cell... - Bartosz
Post your datagrid xaml - netaholic

1 Answers

1
votes

I would also like to validate the data on input

Just use WPF validation capabilities. E.g., IDataErrorInfo-based validation:

public class RowViewModel : INotifyPropertyChanged, IDataErrorInfo
{
    // INPC implementation is omitted

    public string Id
    {
        get { return id; }
        set
        {
            if (id != value)
            {
                id = value;
                OnPropertyChanged();
            }
        }
    }
    private string id;

    public string this[string columnName]
    {
        get
        {
            if (string.IsNullOrEmpty(Id))
            {
                return "Id cannot be an empty string.";
            }

            return null;
        }
    }

    public string Error
    {
        get { return null; }
    }
}

    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Rows}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Id" Binding="{Binding Id, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/>
        </DataGrid.Columns>
    </DataGrid>

the user might provide an incorrect Id, in which case I don't want to add it to the collection

You can't.

When DataGrid uses in-place editing, adding new row automatically adds new item into the bound ItemsSource. But if the row data source uses validation, user can't commit changes until there are validation errors.

In this case user has one way to go - to cancel editing, and when he cancels, DataGrid removes new row from the underlying ItemsSource.