Deserializing the contents of a listview

不打扰是莪最后的温柔 提交于 2019-12-12 02:48:33

问题


I have a ListView which contains ListViewItems. I have the following code to serialize my list view, at the moment this just creates a file with the 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();
}

What I'm having problems with is going about de serializing the contents of this file into a ListView.

Can anyone explain how I would do this?

So far for a deserialize method I have:

private void DeSerialize()
{
    FileStream filestream = File.Open(@"H:\test1.xaml", FileMode.Open);

    XamlReader reader = new XamlReader();
    reader.LoadAsync(filestream);
}

回答1:


You could use the XamlReader class, to load the Xaml from the file and then set the contents of the ListView to it.

Although, this looks like a dead end, so it may be better to serialize the data (ItemsSource) you are using to populate the ListView in the first place. i.e. ViewModel / Model if using the MVVM pattern.

MVVM Pattern (Model View ViewModel)

Because of the binding engine that WPF uses, it is quite useful to use the MVVM pattern in combination with WPF. It also seperates the Display logic from the business and data logic, A View can know about a ViewModel, but the ViewModel doesn't know about the View and shouldn't have logic that dictates what the View will look like. You could also use a dependency injection framework such as MEF to further decouple between the components and aid with Unit Testing.

The Model contains a mixture of data access and state, so you could serialize and deserialize the Model when it comes to saving and loading the ListView items.

The ViewModel is an abstraction of the View. Your application may only have one Model but plenty of Views that are related to it. So the ViewModel would contain any relevant properties you want from the Model to interact with in a current View

Finally the View displays the ViewModel.

So what would this mean code wise?

We end up with two classes and a xaml Window/Page/User Control.

I'll provide some interfaces as a guide.

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; }
}

The View can be done entirely in Xaml, this is useful if you are working on a team with a UI Designer as they can be working on the look and feel without upsetting your work too much in the ViewModel and Model

Xaml uses DataTemplates to describe how UI elements should display their DataContext.

In the View we can add the ViewModel as a resource.

<Window xmlns:vm="clr-namespace:MyApp.MyViewModels">
   <Window.Resources>
      <vm:MyViewModelImplementation x:Key="ViewModel" />
   </Window.Resources>
...

Then we can set the lowest UI elements DataContext to be the ViewModel, for instance you may wish to use a grid as the base ui element.

<Grid DataContext="{StaticResource ViewModel}">
   ...
</Grid>

Now when we display the ListView of items the ListView will look something like this.

<ListView ItemsSource="{Binding Items}">
   <ListView.ItemsTemplate>
      <DataTemplate>
         <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Property1}" />
         </StackPanel>
      <DataTemplate>
   </ListView.ItemsTemplate>
</ListView>

Say you want to be able to add new items to your collection by pressing a Button.

The Xaml markup would look like this:

<Button Command="{Binding Add}">Add</Button>

and the Command property in the ViewModel would be this.

public MyViewModelImplementation()
{
   Add = new RelayCommand(AddItem);
}

private void AddItem()
{
   DispatcherHelper.CheckBeginInvokeOnUI(() =>
   {
      Items.Add(new MyData());
   });
}

Since we are using an ObservableCollection<T> the UI will be updated, but you need to invoke the UI thread since it has to be Modified on the thread it was created from.

MVVM Wiki article MVVMLight



来源:https://stackoverflow.com/questions/17856474/deserializing-the-contents-of-a-listview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!