将 XAML 控件绑定到应用程序数据文件

Binding XAML control to Application Data file

我有一项服务 class,其中包含处理 ApplicatonData

的所有功能
public class AppSettings : INotifyPropertyChanged
{
    private static volatile AppSettings _instance;

    private ApplicationDataContainer _localData;
    private ApplicationDataContainer _roamingData;
    private StorageFolder _localFolder;
    private StorageFolder _roamingFolder;

    ... 
    //Code to make AppSettings a singleton class. 
    //Using AppSettings.Instance to access public properties/methods
    ...

    private void SaveSettings(string key, object value, bool roaming = false)
    {
        if (roaming)
            _roamingData.Values[key] = value;
        else
            _localData.Values[key] = value;
    }

    private T ReadSetting<T>(string key, T defaultValue = default(T), bool roaming = false)
    {
        if (roaming)
        {
            if (_roamingData.Values.ContainsKey(key))
                return (T)_roamingData.Values[key];
        }
        else if (_localData.Values.ContainsKey(key))
            return (T)_localData.Values[key];

        return defaultValue;
    }

    public async void SaveToFile<T>(T obj, string propName, bool roaming = false)
    {
        StorageFile file = await (roaming ? _roamingFolder : _localFolder).CreateFileAsync(propName, CreationCollisionOption.ReplaceExisting);
        await FileIO.WriteTextAsync(file, JsonConvert.SerializeObject(obj), UnicodeEncoding.Utf8);
    }

    public async Task<T> LoadFromFile<T>(string propName, bool roaming = false)
    {
        try
        {
            StorageFile file = await (roaming ? _roamingFolder : _localFolder).GetFileAsync(propName);
            return JsonConvert.DeserializeObject<T>(await FileIO.ReadTextAsync(file, UnicodeEncoding.Utf8));
        }
        catch (Exception)
        {
            return default;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged([CallerMemberName]string propName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }


    //List all setting here
    public string exampleProp
    {
        get => ReadSetting<string>(nameof(exampleProp));
        set
        {
            SaveSettings(nameof(movie_staging_folder), value, false);
            NotifyPropertyChanged();
        }
    }

    ... 
    // Other properties
    ...
}

这适用于单值属性,例如:

<TextBox Text="{x:Bind services:AppSettings.Instance.exampleProp, Mode=TwoWay}"
         ... />

我的问题是绑定到多值属性。我有一个 ListView 显示用户选择的目录列表。我制作了 SaveToFile()LoadFromFile() 来(反)序列化一个对象,在我的例子中是一个 ObservableCollection,并且 save/load 它作为 ApplicationData 文件夹中的一个文件。我不知道如何将其绑定到 ListView ItemsSource.

您可以在 ObservableCollection 中声明一个 属性 以从 LoadFromFile() 接收反序列化的集合并将 属性 绑定到 listView 的 ItemsSource。

public AppSettings()
{
    InitializeMyList();​
}​

private async void InitializeMyList() 
{
    myLists = await LoadFromFile<ObservableCollection<String>>("");​
}
private ObservableCollection<string> myLists = new ObservableCollection<string>();
public ObservableCollection<string> MyLists 
{
    get {
        return myLists;
    }
    set {
            ......
    }
}

.xaml:

<ListView ItemsSource="{x:Bind services:AppSettings.Instance.MyLists}"></ListView>