假设我在带有会话数据的Windows应用商店应用程序的主框架中有一个列表。单击某个项目时,将打开一个新框架,我可以在其中编辑数据。
如何在帧之间正确共享会话数据,以及如何保存和恢复会话数据以使对象之间的引用完好无损?
我知道在创建新帧时我可以将对象作为参数发送。我也知道如何保存/恢复会话数据。我只是不知道如何解决这个问题:)。
答案 0 :(得分:1)
您可以使用NavigationService将数据发送到新帧,如下面的选项中所述。它更像是发送keyvalur对作为uri参数:
NavigationService.Navigate(new Uri("/Page1.xaml?parameter1=p1¶meter2=p2", UriKind.Relative));
获得价值:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string parameterValue = NavigationContext.QueryString["parameter"];
}
http://www.geekchamp.com/tips/how-to-pass-data-between-pages-in-windows-phone-alternatives
此外,如果您想共享复杂的对象,您可能需要创建嵌套的视图模型,但如果由于视图的性质而没有奢侈的嵌套视图模型,那么您可能需要创建静态应用缓存以使用介质来保持/在框架之间共享对象。
答案 1 :(得分:1)
存储对象的全局引用并不是那么棘手。你可以拥有一个静态的持有者,他或她没有责任坚持下去。哦,像这样:
public interface IViewModel { }
public class ViewModelOne : IViewModel { }
public class ViewModelTwo : IViewModel { }
public class ViewModelThree : IViewModel { }
public static class GlobalObjects
{
private static ViewModelOne viewModelOne = null;
public static ViewModelOne ViewModelOne
{
get { return Get<ViewModelOne>(ref viewModelOne); }
set { Set(ref viewModelOne, value); }
}
private static T Get<T>(ref T storage) where T : IViewModel, new()
{
if (storage != null)
return storage;
try
{
var json = Load(typeof(T).ToString());
return storage = Deserialize<T>(json);
}
catch (Exception)
{
return new T();
}
}
private static void Set<T>(ref T storage, T value) where T : IViewModel
{
if (storage?.Equals(value))
return;
try
{
var json = Serialize(value);
Save(json, typeof(T).ToString());
}
catch (Exception)
{
Save(string.Empty, typeof(T).ToString());
}
}
private static void Save(string value, string key)
{
throw new NotImplementedException();
}
private static string Serialize(object obj)
{
throw new NotImplementedException();
}
private static string Load(string key)
{
throw new NotImplementedException();
}
private static T Deserialize<T>(string obj)
{
throw new NotImplementedException();
}
}
祝你好运! //杰瑞
答案 2 :(得分:0)
在Shoaib Shaikh获得一些灵感后,我决定建立一个全球存储库。请查看这个原因我几乎不知道我在做什么: - )。
我有三节课。所有类都使用DataContract,因此很容易序列化。第一个PersonViewModel非常简单:
[DataContract()]
public class PersonViewModel : BaseViewModel
{
public PersonViewModel(string name)
{
Name = name;
}
#region Name property
[DataMember()]
private string _Name;
public string Name
{
get
{
return _Name;
}
set
{
SetPropertyValue(ref _Name, value, () => Name);
}
}
#endregion
}
其次是PersonListViewModel。每个PersonViewModel都存储在一个带有字符串id的全局哈希表中。本课程负责ID:s。通过调用RefreshPersonCollection,可以从全局对象重建人员列表。相当笨拙,最好是按要求接待这些人,但我现在太累了,无法解决这个问题: - )。
[DataContract()]
public class PersonListViewModel : BaseViewModel
{
[DataMember()]
private List<string> PersonIds = new List<string>();
public PersonListViewModel()
{
Persons = new ObservableCollection<PersonViewModel>();
CreateDefaultData();
}
public void CreateDefaultData()
{
for(int i=0; i<3; i++)
{
string personid = Guid.NewGuid().ToString();
string personname = "Person " + personid;
PersonViewModel person = new PersonViewModel(personname);
PersonIds.Add(personid);
Persons.Add(person);
SharedObjects.Instance.Objects[personid] = person;
}
}
public void RefreshPersonCollection()
{
Persons = new ObservableCollection<PersonViewModel>();
foreach (string personid in PersonIds)
{
Persons.Add((PersonViewModel)SharedObjects.Instance.Objects[personid]);
}
}
public ObservableCollection<PersonViewModel> Persons{ get; set; }
}
第三类是我的全局存储库。我想也很直截了当。所有PersonViewModels和所有PersonListViewModel都存储在此存储库中。
[DataContract()]
public class SharedObjects
{
public static SharedObjects Instance;
public SharedObjects()
{
Objects = new Dictionary<string, object>();
}
public void Init()
{
Objects["mainviewmodel"] = new PersonListViewModel();
}
[DataMember()]
private Dictionary<string, Object> _Objects;
public Dictionary<string, Object> Objects
{
get { return _Objects; }
set { _Objects = value; }
}
}
在我的Windows商店应用程序中,我有一个SuspensionManager,我稍微修改了它以序列化和反序列化我的全局存储库。
第一个更改是将我的新类型添加到要序列化的已知类型。我不喜欢这样,希望这些类能以某种方式自己完成(据我所知,这是可能的)。
static SuspensionManager()
{
_knownTypes.Add(typeof(SharedObjects));
_knownTypes.Add(typeof(PersonListViewModel));
_knownTypes.Add(typeof(PersonViewModel));
}
SaveAsync中的第二个更改是确保保存全局数据。只添加了一行:
//I added this:
_sessionState["globalobjects"] = SharedObjects.Instance;
// Serialize the session state synchronously to avoid asynchronous access to shared
// state
MemoryStream sessionData = new MemoryStream();
DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), _knownTypes);
serializer.WriteObject(sessionData, _sessionState);
第三次更改是在RestoreAsync中。
// Get the input stream for the SessionState file
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(sessionStateFilename);
using (IInputStream inStream = await file.OpenSequentialReadAsync())
{
// Deserialize the Session State
DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), _knownTypes);
_sessionState = (Dictionary<string, object>)serializer.ReadObject(inStream.AsStreamForRead());
}
//I added this:
if (_sessionState.ContainsKey("globalobjects"))
SharedObjects.Instance = (SharedObjects) _sessionState["globalobjects"];
这感觉很易于管理,但任何改进建议都值得赞赏:-)。这也适用于Windows Phone(SuspensionManager除外,但我想这个平台上的内容类似)?