0

Подскажите пожалуйста, что я делаю не правильно. Пробую сохранять в xml файле получается, но обратно в таблицу загрузка не происходит, подскажите в чём моя ошибка? Спасибо.

<Window x:Class="XmlSearilization.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <DataGrid Name="grd" Grid.Row="0"  ItemsSource="{Binding All}" 
                          AutoGenerateColumns="False" CanUserAddRows="True">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding id}" Header="№" IsReadOnly="True" Width="Auto" />
                <DataGridTextColumn Binding="{Binding Name}" Header="Имя" Width="Auto"/>
                <DataGridTextColumn Binding="{Binding SecondName}" Header="Фамилия" Width="Auto"/>
            </DataGrid.Columns>
        </DataGrid>
        <StackPanel Margin="2" Grid.Row="1" Orientation="Horizontal">
            <Button Command="{Binding SaveCommand}" Margin="5"
                            Click="Button_Click">Сохранить в XML</Button>
        </StackPanel>
    </Grid>
</Window>
[Serializable]
public class Settings
{
    public static string Path = "config.xml";
}

public class Person : ViewModelBase
{
    public int id
    {
        get { return ID; }
        set
        {
            ID = value;
            base.RaisePropertyChangedEvent("id");
        }
    }
    private int ID { get; set; }
    public string Name { get; set; }
    public string SecondName { get; set; }
    public Person()
    { }

    public static void Save(string path, Person[] subds)
    {
        XmlSerializer formatter = new XmlSerializer(subds.GetType());

        using (FileStream fs = new FileStream(path, FileMode.Create))
        {
            formatter.Serialize(fs, subds);
        }

    }

    public static IEnumerable<Person> Load(string path)
    {
        XmlSerializer formatter = new XmlSerializer(typeof(Person[]));
        if (File.Exists(path))
            using (FileStream fs = new FileStream(path, FileMode.Open))
            {
                var subds = formatter.Deserialize(fs) as Person[];
                if (subds != null)
                    return subds;
            }

        return Enumerable.Empty<Person>();
    }
}

public class MainViewModel : ViewModelBase
{
    private ICommand saveCommand;
    public ObservableCollection<Person> All { get; set; }
    public void Save(object p = null)
    {
        Person.Save(Settings.Path, All.ToArray());
    }
    public MainViewModel(IEnumerable<Person> all)
    {
        All = new ObservableCollection<Person>(all);
        saveCommand = new RelayCommand(Save);
    }
    public MainViewModel() : this(Person.Load(Settings.Path))
    {
        All = new ObservableCollection<Person>();
        All.CollectionChanged += OnGroceryListChanged;
        this.All = NumberService.SetCollection(this.All);
    }
    void OnGroceryListChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        NumberService.SetCollection(this.All);
    }
    public ICommand SaveCommand
    {
        get { return saveCommand; }
        set { saveCommand = value; }
    }
}

public class RelayCommand : ICommand
{
    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;
    public RelayCommand(Action<object> execute)
        : this(execute, null)
    {
    }
    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }
    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    public void Execute(object parameter)
    {
        _execute(parameter);
    }
}

public static class NumberService
{
    public static ObservableCollection<T> SetCollection<T>(ObservableCollection<T>
       targetCollection) where T : Person
    {
        // Initialize
        var Number = 1;

        // Resequence
        foreach (Person sequencedObject in targetCollection)
        {
            sequencedObject.id = Number;
            Number++;
        }
        // Set return value
        return targetCollection;
    }
}
EvgeniyZ
  • 15,694

1 Answers1

1

Десериализация срабатывает нормально.

Обратите внимание на свой конструктор без параметров:

public MainViewModel() : this(Person.Load(Settings.Path))
{
    All = new ObservableCollection<Person>();
    All.CollectionChanged += OnGroceryListChanged;
    this.All = NumberService.SetCollection(this.All);
}

После успешной загрузки данных во втором конструкторе, который вы вызываете через this(...), вы затираете коллекцию: All = new ObservableCollection<Person>(), думаю, эта строчка здесь лишняя.

При использовании отладчика такие ошибки отлавливаются очень легко, обязательно научитесь им пользоваться.

Как и какими средствами находить ошибки в коде на C#?

  • Спасибо, буду учиться изучать ошибки, а то действительно у меня сложность с этим. – Евгений Jun 18 '18 at 08:37
  • Никак не могу заставить себя не забывать галочки ставить:))) – Евгений Jun 19 '18 at 21:40