我有一个包含ListViewItems的ListView。我有以下代码来序列化我的列表视图,此时这只是用xaml创建一个文件。
private void SerializeToXML()
{
FileStream filestream = File.Create(@"H:\test1.xaml");
StreamWriter streamwriter = new StreamWriter(filestream);
foreach (ListViewItem Item in slideListView.Items)
{
string mystrXAMLWrite = XamlWriter.Save(Item.Tag);
streamwriter.Write(mystrXAMLWrite);
}
streamwriter.Close();
filestream.Close();
}
我遇到的问题是将此文件的内容序列化为ListView。
有谁可以解释我会怎么做?
到目前为止,我有一个反序列化方法:
private void DeSerialize()
{
FileStream filestream = File.Open(@"H:\test1.xaml", FileMode.Open);
XamlReader reader = new XamlReader();
reader.LoadAsync(filestream);
}
答案 0 :(得分:1)
您可以使用XamlReader
类从文件加载Xaml,然后将ListView的内容设置为它。
虽然这看起来像死路一条,所以最好序列化你用来填充ListView的数据(ItemsSource)。即,如果使用MVVM模式,则为ViewModel / Model。
由于WPF使用的绑定引擎,将MVVM模式与WPF结合使用非常有用。 它还从业务和数据逻辑中分离显示逻辑,查看可以了解 ViewModel ,但 ViewModel 不知道查看并且不应该有逻辑来决定查看的外观。您还可以使用依赖注入框架(如MEF)进一步在组件之间进行分离,并辅助单元测试。
模型包含数据访问和状态的混合,因此您可以在保存和加载ListView项目时序列化和反序列化模型。
ViewModel 是查看的抽象。您的应用程序可能只有一个模型,但有大量与其相关的视图。因此, ViewModel 将包含您希望模型在当前视图
中进行交互的所有相关属性最后,查看会显示 ViewModel 。
那么这对代码来说意味着什么?
我们最终得到两个类和一个xaml Window / Page / User Control。
我将提供一些界面作为指南。
public interface IMyData : INotifyPropertyChanged
{
Properties...
}
public interface IMyModel
{
IList<IMyData> Items { get; set; }
void Serialize(string filePath);
void Deserialize(string filePath);
}
public interface IMyViewModel : INotifyPropertyChanged
{
IMyModel Model { get; set; }
ObservableCollection<IMyData> Items { get; set; }
ICommand Save { get; }
ICommand Load { get; }
ICommand Add { get; }
ICommand Remove { get; }
}
视图可以完全在Xaml中完成,如果你正在与一个拥有UI设计师的团队合作,这很有用,因为他们可以在外观和感觉上工作而不会过多地扰乱你的工作 ViewModel 和模型
Xaml 使用DataTemplates
来描述UI元素应如何显示其DataContext
。
在查看中,我们可以添加 ViewModel 作为资源。
<Window xmlns:vm="clr-namespace:MyApp.MyViewModels">
<Window.Resources>
<vm:MyViewModelImplementation x:Key="ViewModel" />
</Window.Resources>
...
然后我们可以将最低的UI元素DataContext设置为ViewModel,例如,您可能希望使用网格作为基本的ui元素。
<Grid DataContext="{StaticResource ViewModel}">
...
</Grid>
现在,当我们显示ListView
个项目时,ListView
将会显示如下内容。
<ListView ItemsSource="{Binding Items}">
<ListView.ItemsTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Property1}" />
</StackPanel>
<DataTemplate>
</ListView.ItemsTemplate>
</ListView>
假设您希望能够通过按Button
。
Xaml标记看起来像这样:
<Button Command="{Binding Add}">Add</Button>
并且 ViewModel 中的Command属性就是这个。
public MyViewModelImplementation()
{
Add = new RelayCommand(AddItem);
}
private void AddItem()
{
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
Items.Add(new MyData());
});
}
由于我们使用ObservableCollection<T>
,UI将被更新,但您需要调用UI线程,因为它必须在创建它的线程上进行修改。