Я не понимаю одну ошибку в моем коде. Я использую DataGrid. Я закодировал методы обновления, добавления и удаления данных непосредственно из сетки данных.
Ниже приведен код сетки данных моего представления.
<DataGrid Grid.Row="1" Grid.Column="1" Grid.RowSpan="1" Grid.ColumnSpan="1"
Margin="5,0,10,0"
AutoGenerateColumns="False"
AlternatingRowBackground="LightGray"
CanUserResizeColumns="False"
CanUserResizeRows="False"
CanUserAddRows="True"
ItemsSource="{Binding DataGridSource}"
SelectedItem="{Binding SelectedItem, Converter={StaticResource ResourceKey=ConverterKey}}">
<DataGrid.Columns>
<DataGridTextColumn Width="40" Header="IDetape" Binding="{Binding IDEtape}" />
<DataGridTextColumn Width="40" Header="IDrecipe" Binding="{Binding IDRecipe}" />
<DataGridTextColumn Width="40" Header="Etape" Binding="{Binding EtapeOrdre}" />
<DataGridTextColumn Width="*" Header="Description" Binding="{Binding EtapeDescription}" />
</DataGrid.Columns>
</DataGrid>
Моя модель очень проста:
public class RecipeEtape : ViewModelBase
{
#region Variable
private string _idEtape;
private string _idRecipe;
private string _etapeOrdre;
private string _etapeDescription;
#endregion Variable
#region Constructor
#endregion Constructor
#region Properties
public string IDEtape
{
get
{
return _idEtape;
}
set
{
_idEtape = value;
OnPropertyChanged("IDEtape");
}
}
public string IDRecipe
{
get
{
return _idRecipe;
}
set
{
_idRecipe = value;
OnPropertyChanged("IDRecipe");
}
}
public string EtapeOrdre
{
get
{
return _etapeOrdre;
}
set
{
_etapeOrdre = value;
OnPropertyChanged("EtapeOrdre");
}
}
public string EtapeDescription
{
get
{
return _etapeDescription;
}
set
{
_etapeDescription = value;
OnPropertyChanged("EtapeDescription");
}
}
#endregion Properties
}
И это весь код для управления сеткой данных (Добавить / обновить / удалить)
#region <!------------------------ PROPRIETES PARTIE DROITE .XAML -------------------------->
private ObservableCollection<RecipeEtape> _dataGridSource;
public ObservableCollection<RecipeEtape> DataGridSource
{
get
{
return _dataGridSource;
}
set
{
_dataGridSource = value;
OnPropertyChanged("DataGridSource");
}
}
private RecipeEtape _selectedItem;
public RecipeEtape SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
OnPropertyChanged("SelectedItem");
}
}
#endregion <!------------------------ PROPRIETES PARTIE DROITE .XAML -------------------------->
#region <!------------------------ PRIVATE METHOD PARTIE DROITE .XAML -------------------------->
private void loadData_DataGrid()
{
foreach (var item in RecipeEtapeProvider.selectAll(_listViewRecetteSelectedItem.Name))
{
_dataGridSource.Add(new RecipeEtape
{
IDEtape = item.IDEtape,
IDRecipe = item.IDRecipe,
EtapeOrdre = item.EtapeOrdre,
EtapeDescription = item.EtapeDescription,
});
}
subscribeEvent();
_dataGridSource.CollectionChanged += DataGridSource_CollectionChanged;
}
private void subscribeEvent()
{
foreach (RecipeEtape obj in _dataGridSource)
{
obj.PropertyChanged += onPropertyChanged;
}
}
private void onPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (_selectedItem.IDEtape != null)
{
RecipeEtape obj = new RecipeEtape()
{
IDEtape = _selectedItem.IDEtape,
IDRecipe = _listViewRecetteSelectedItem.Name,
EtapeOrdre = _selectedItem.EtapeOrdre,
EtapeDescription = _selectedItem.EtapeDescription,
};
RecipeEtapeProvider.updateItem(obj);
}
else
{
RecipeEtape obj = new RecipeEtape()
{
// IDEtape = "", Incrément auto fait par DB - TODO : Faire soi-même l'AI
IDRecipe = _listViewRecetteSelectedItem.Name,
EtapeOrdre = _selectedItem.EtapeOrdre,
EtapeDescription = _selectedItem.EtapeDescription,
};
//RecipeEtapeProvider.addItem(obj);
_selectedItem.IDEtape = (int.Parse(RecipeEtapeProvider.selectLastID()) + 1).ToString();
}
}
private void DataGridSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
RecipeEtape obj;
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
obj = (RecipeEtape)e.NewItems[0];
if (obj.IDEtape == null)
{
obj.PropertyChanged += onPropertyChanged;
}
break;
case NotifyCollectionChangedAction.Remove:
obj = (RecipeEtape)e.OldItems[0];
if (e.OldItems != null)
{
obj.PropertyChanged -= onPropertyChanged;
deleteItem(e.OldItems.Cast<object>().ToList());
}
break;
default:
break;
}
}
#endregion <!------------------------ PRIVATE METHOD PARTIE DROITE .XAML -------------------------->
Теперь, когда я добавляю данные, я создаю объект RecipeEtape
(метод onPropertyChanged
). внутри теста else
). Этот объект собирает данные со свойством _selectedItem
.
IDRecipe = _listViewRecetteSelectedItem.Name, ---> return what's needed
EtapeOrdre = _selectedItem.EtapeOrdre, ---> return NULL, and I don't know why
EtapeDescription = _selectedItem.EtapeDescription, ---> return what's needed
Это странное поведение, потому что он работает для _selectedItem.EtapeDescription
. Не могли бы вы мне помочь?
PS: Извините за комбинацию имен переменных "French-Engli sh"
EDIT "код преобразователя":
public class ConverterService : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && string.Equals("{NewItemPlaceholder}", value.ToString(), StringComparison.Ordinal))
{
return null;
}
return value;
}
}