Kylo Ren
Kylo Ren

Reputation: 8813

Unable to add new Row in DataGrid UI automatically

I'm unable to add new rows in my DataGrid from UI. Below is my code.

<DataGrid CanUserAddRows="True" Name="dg"  ItemsSource="{Binding list}"  AutoGenerateColumns="False" >
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Path=.}" Header="Text"/>
        <DataGridTextColumn Binding="{Binding Length}" Header="Length"/>            
    </DataGrid.Columns>
</DataGrid>

list is a list of string in above Binding.Usually when I set CanUserAddRows="True" I was able to add rows on UI automatically in other examples.

My property is as following:

public List<string> list { get; set; }

And before display of DataGrid it has been initialized. So no need to implement INotifyPropertyChanged for this property.

Can someone explain me why the DataGrid is behaving this way? How to achieve desired behavior?

Upvotes: 0

Views: 1605

Answers (1)

Steve Wong
Steve Wong

Reputation: 2256

The problem is that string does not have a parameter-less constructor, so the grid can't create a new instance for the empty grid row that allows the user to add a new row. Further, the grid can't "set" the "." property onto the string.

One option is to create your own class that exposes Text and Length properties:

public class StringMember : INotifyPropertyChanged
{
private string m_actualString;
public string Text
{
    get { return m_actualString; }
    set
    {
        m_actualString = value;
        //OnPropertyChanged("Text");
        //OnPropertyChanged("Length");
    }
}

public int Length { get { return Value.Length; } }

//public event PropertyChangedEventHandler PropertyChanged;        
//protected virtual void OnPropertyChanged(string propertyName = null)
//{
//    PropertyChangedEventHandler handler = PropertyChanged;
//    if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
//}

}

Then, your XAML would bind to your properties:

<DataGrid CanUserAddRows="True" Name="dg"  ItemsSource="{Binding list}"  AutoGenerateColumns="False" >
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Text}" Header="Text"/>
        <DataGridTextColumn Binding="{Binding Length}" Header="Length"/>            
    </DataGrid.Columns>
</DataGrid>

In this case, your "list" property would be List<StringMember> or ObservableCollection<StringMember> instead of string.

Upvotes: 5

Related Questions