I'm trying to create a custom DataGrid based on the WPF's DataGrid control. I created another property called "ItemsDataSource" and use it to bind collections from my ViewModels. When this property raises the ValueChanged event, it sets the value of ItemsSource to the value of ItemsDataSource.
This works fine when the grid is in Read Only mode, but when I set the property CanUserAddRows to True, if the ItemsDataSource is empty, my DataGrid never shows the new line to add new rows. BUT, if I change the binding back to ItemsSource instead of my ItemsDataSource, the DataGrid shows the new line.
Here is the partial code for my custom Grid:
public partial class NewDataGrid : DataGrid
{
public NewDataGrid()
{
InitializeComponent();
var dpd = DependencyPropertyDescriptor.FromProperty(ItemsDataSourceProperty, typeof(NewDataGrid));
dpd?.AddValueChanged(this, (s, a) =>
{
ItemsSource = ItemsDataSource.Cast<object>().ToList();
});
}
public IList ItemsDataSource
{
get { return (IList)GetValue(ItemsDataSourceProperty); }
set { SetValue(ItemsDataSourceProperty, value); }
}
public static readonly DependencyProperty ItemsDataSourceProperty =
DependencyProperty.Register("ItemsDataSource", typeof(IList), typeof(NewDataGrid), new PropertyMetadata(null));
}
And here is how I'm doing the binding in XAML:
<WPF:NewDataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
ItemsDataSource="{Binding Path=DataContext.DataWrapperList, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}"
SelectedValue="{Binding Path=DataContext.SelectedDataWrapper, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}"
AutoGenerateColumns="False"
Validation.ErrorTemplate="{x:Null}"
Margin="0"
VerticalScrollBarVisibility="Auto"
SelectionMode="Single"
CanUserAddRows="True"
CanUserDeleteRows="True"
IsReadOnly="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" Width="*" SortMemberPath="Name" />
<DataGridTextColumn Header="Quantity" Binding="{Binding Path=Quantity}" Width="*" SortMemberPath="Quantity" />
</WPF:PAENewDataGrid>
Here is how the DataListWrapper property is declared in my DataContext:
public ObservableCollection<DataWrapper> DataWrapperList;
Here is my DataWrapper class:
public class DataWrapper : BaseWrapper
{
private DataWrapperDTO _data;
public DataWrapper()
{
_data = new DataWrapperDTO();
}
public DataWrapper(DataWrapperDTO data)
{
_data = data;
}
public string Name
{
get { return _data.Name; }
set
{
_data.Name = value;
RaisePropertyChanged(nameof(Name));
}
}
public int Quantity
{
get { return _data.Quantity; }
set
{
_data.Quantity = value;
RaisePropertyChanged(nameof(Quantity));
}
}
}
Does anyone know how to force the DataGrid to always show this new line whenever the CanUserAddRows property is set to True?
DataWrapperList
property. Another thing i would check is to remove theCast<object>().ToList()
inItemsSource = ItemsDataSource.Cast<object>().ToList();
. I'm currently not in front of a pc with vs to check it, but i guess theItemsSource
only is aList<object>
with one item in the list. – Martin BackaschDataListWrapper property
is not a property but a field. It probably needs to be a property. – grek40