简体   繁体   中英

WPF: store objects inside application settings.settings file

I build a simple ClipboardManager that hold all last Copy item. So i have this simple ClipboardItem class:

public class ClipboardItem : INotifyPropertyChanged
{
    private string _text { get; set; }
    private int _index { get; set; }

    public string Text
    {
        get { return _text; }
        set
        {
            _text = value;
            NotifyPropertyChanged();
        }
    }

    public int Index
    {
        get { return _index; }
        set
        {
            _index = value;
            NotifyPropertyChanged();
        }
    }

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

And my ViewModel class that hold ObservableCollection<ClipboardItem> :

public class ViewModel : INotifyPropertyChanged
{
    private ObservableCollection<ClipboardItem> _clipboards;

    public ViewModel()
    {
        if (_clipboards == null)
        {
            _clipboards = new ObservableCollection<ClipboardItem>();
            _clipboards.CollectionChanged += _clipboards_CollectionChanged;
        }
    }

    private void _clipboards_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        for (int i = 0; i < _clipboards.Count; i++)
            _clipboards[i].Index = i + 1;
    }

    public ObservableCollection<ClipboardItem> Clipboards
    {
        get { return _clipboards; }
        set
        {
            _clipboards = value;
            NotifyPropertyChanged();
        }
    }

    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

So every Copy create new ClipboardItem object inside list but when i restart the application all the records gone so i wonder if there any way to store all my ClipboardItem object inside the application settings.settings file.

//Variable Creation

    private string _dataFileName = @"ClipData.xml";
    DataTable _clipDataTable = new DataTable();

Inside ViewModel constructor.

public ViewModel()
{
    if (_clipboards == null)
    {
        _clipboards = new ObservableCollection<ClipboardItem>();
        _clipboards.CollectionChanged += _clipboards_CollectionChanged;

    }

        InitDataTable();
        ReadDataFile();
}

Create new Methods

        /// <summary>
    /// Initialize Data Table considering you have only 1 column data.
    /// If you have more then you need to create more columns
    /// </summary>
    private void InitDataTable()
    {
        _clipDataTable = new DataTable();
        _clipDataTable.Columns.Add("ClipHeader");
        _clipDataTable.AcceptChanges();
    }

    //the clipboard Data is saved in xml file.
    private void WriteDataFile()
    {
        DataSet ClipDataSet = new DataSet();
        ClipDataSet.Tables.Add(_clipDataTable);
        ClipDataSet.WriteXml(_dataFileName);
    }

   // if file exits then read the xml file and add it to the Collection, which will be reflected in UI.
    private void ReadDataFile()
    {
        DataSet ClipDataSet = new DataSet();
        if (File.Exists(_dataFileName))
        {
            ClipDataSet.ReadXml(_dataFileName);

            foreach (DataRow item in ClipDataSet.Tables[0].Rows)
            {
                Clipboards.Add(new ClipboardItem { Text = Convert.ToString(item["ClipHeader"]) });
            }
        }
    }

Using Command you can bind Method of ViewModel to Window Closing event. So whenever the user closes the window, the data in the collection will be written into the Xml file.

Data from the Collection is copied into DataTable.

    private void WindowCloseCommadn(object o)
    {
        foreach (var item in Clipboards)
        {
            DataRow dataRow = _clipDataTable.NewRow();
            dataRow["ClipHeader"] = item.Text;
            _clipDataTable.Rows.Add(dataRow);
        }
        WriteDataFile();
    }

Update:-

Same Code without ViewModel, by making the codebehind class has the DataContext for binding Collection.

    /// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{

    private ClipboardMonitor clipboardMonitor;
    private string _dataFileName = @"ClipData.xml";
    DataTable _clipDataTable = new DataTable();
    public ObservableCollection<ClipboardItem> Clipboards { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        Clipboards = new ObservableCollection<ClipboardItem>();
        Clipboards.CollectionChanged += Clipboards_CollectionChanged;

        Loaded += MainWindow_Loaded;
        InitiateClipboardMonitor();
        this.Closing += MainWindow_Closing1;
        this.DataContext = this;
    }

    private void MainWindow_Closing1(object sender, CancelEventArgs e)
    {
        foreach (var item in Clipboards)
        {
            DataRow dataRow = _clipDataTable.NewRow();
            dataRow["ClipHeader"] = item.Text;
            _clipDataTable.Rows.Add(dataRow);
        }
        WriteDataFile();
    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        InitDataTable();
        ReadDataFile();
    }

    /// <summary>
    /// Initialize Data Table considering you have only 1 column data.
    /// If you have more then you need to create more columns
    /// </summary>
    private void InitDataTable()
    {
        _clipDataTable = new DataTable();
        _clipDataTable.Columns.Add("ClipHeader");
        _clipDataTable.AcceptChanges();
    }

    private void WriteDataFile()
    {
        DataSet ClipDataSet = new DataSet();
        ClipDataSet.Tables.Add(_clipDataTable);
        ClipDataSet.WriteXml(_dataFileName);
    }

    private void ReadDataFile()
    {
        DataSet ClipDataSet = new DataSet();
        if (File.Exists(_dataFileName))
        {
            ClipDataSet.ReadXml(_dataFileName);

            foreach (DataRow item in ClipDataSet.Tables[0].Rows)
            {
                Clipboards.Add(new ClipboardItem { Text = Convert.ToString(item["ClipHeader"]) });
            }
        }
    }

    private void Clipboards_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        for (int i = 0; i < Clipboards.Count; i++)
        {
            Clipboards[i].Index = i + 1;
        }
    }

    private void InitiateClipboardMonitor()
    {
        clipboardMonitor = new ClipboardMonitor();
        clipboardMonitor.OnClipboardContentChanged += ClipboardMonitor_OnClipboardContentChanged; ;
    }

    private void ClipboardMonitor_OnClipboardContentChanged(object sender, EventArgs e)
    {
        string clipboardText = Clipboard.GetText(TextDataFormat.Text);
        Clipboards.Add(new ClipboardItem { Text = clipboardText });
    }
}

to know about Command, refer the article

https://www.codeproject.com/Articles/274982/Commands-in-MVVM

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM