2017-03-27 19 views
0

我需要序列化包含圖像和文本框的ContentControl列表,以便將它們保存到二進制文件中。如何製作C#WPF ContentControl可序列化?

在組件中的錯誤消息

類型 'System.Windows.Controls.ContentControl' 'PresentationFramework,版本= 4.0.0.0,文化=中性公鑰= 31bf3856ad364e35' 未標記爲可序列。」

+2

歐比旺說:「這不是你正在尋找的方式。」 –

+0

我看到...什麼是保存這些contentcontrol對象的最佳方式是? – khuang

+1

不要嘗試保存內容控件。他們的主要目的是與用戶交互 –

回答

0

您不能連載一個控制,因爲它們是視圖狀態

如果你是以下MVVM那麼你的控件應顯示視圖模型,並且視圖模型將被操縱模型,以及模型是你應該連載

這裏就是一個例子

XAML

<Window 
    x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:WpfApplication1" 
    Title="MainWindow" Height="350" Width="525"> 
    <Window.DataContext> 
     <local:ViewModel x:Name="vm" /> 
    </Window.DataContext> 
    <Window.Resources> 
     <CollectionViewSource x:Key="cvs" Source="{Binding Collection}"/> 
    </Window.Resources> 
    <StackPanel> 
     <GroupBox Header="New Item"> 
      <StackPanel> 
       <GroupBox Header="Text"> 
        <TextBox Text="{Binding NewText}"/> 
       </GroupBox> 
       <GroupBox > 
        <GroupBox.Header> 
         <Button Command="{Binding Browse, Mode=OneWay}">Uri</Button> 
        </GroupBox.Header> 
        <TextBox Text="{Binding NewUri}"/> 
       </GroupBox> 
       <Button Command="{Binding Add, Mode=OneWay}" >Add</Button> 
      </StackPanel> 
     </GroupBox > 
     <ListView ItemsSource="{Binding Mode=OneWay, Source={StaticResource cvs}}" IsSynchronizedWithCurrentItem="True"> 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <GroupBox Header="{Binding Text}"> 
         <Image Source="{Binding Uri}" Stretch="None"/> 
        </GroupBox> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
     </ListView> 
     <StackPanel Orientation="Horizontal"> 
      <Button Command="{Binding Delete, Mode=OneWay}" CommandParameter="{Binding /, Mode=OneWay, Source={StaticResource cvs}}" >Delete</Button> 
      <Button Command="{Binding Cancel, Mode=OneWay}" >Cancel</Button> 
      <Button Command="{Binding Save, Mode=OneWay}" >Save</Button> 
      <Button Command="{Binding Load, Mode=OneWay}" >Load</Button> 
     </StackPanel> 
    </StackPanel> 
</Window> 

模型

[Serializable] 
public class ImageModel 
{ 
    public string Text { get; set; } 
    public Uri Uri { get; set; } 
} 

public class ImageCollectionModel 
{ 
    public List<ImageModel> Collection { get; } = new List<ImageModel>(); 

    private BinaryFormatter Formatter = new BinaryFormatter(); 
    public bool Save(FileInfo file) 
    { 
     try 
     { 
      using (var stream = file.OpenWrite()) 
      { 
       Formatter.Serialize(stream, Collection); 
       return true; 
      } 
     } 
     catch (Exception) 
     { 
      return false; 
     } 
    } 
    public bool Load(FileInfo file) 
    { 
     try 
     { 
      using (var stream = file.OpenRead()) 
      { 
       var col = Formatter.Deserialize(stream) as List<ImageModel>; 
       Collection.Clear(); 
       Collection.AddRange(col); 
       return true; 
      } 
     } 
     catch (Exception) 
     { 
      return false; 
     } 
    } 
} 

視圖模型

public class ViewModel:BindableBase 
{ 
    public ViewModel() 
    { 
     Add = new DelegateCommand(() => Collection.Add(new ImageModel() 
     { 
      Text = NewText, 
      Uri = new Uri(NewUri) 
     })); 
     Delete = new DelegateCommand<ImageModel>(item => Collection.Remove(item)); 
     Load = new DelegateCommand(() => 
     { 
      var open = new Microsoft.Win32.OpenFileDialog(); 
      if (open.ShowDialog() ?? false) 
      { 
       var file = new FileInfo(open.FileName); 
       if (file.Exists) 
       { 
        if (Model == null) 
        { 
         Model = new ImageCollectionModel(); 
        } 
        Model.Load(file); 
       } 
       Cancel.Execute(); 
      } 

     }); 
     Save = new DelegateCommand(() => 
     { 
      var save = new Microsoft.Win32.SaveFileDialog(); 
      if (save.ShowDialog() ?? false) 
      { 
       var file = new FileInfo(save.FileName); 
       if (!file.Exists) 
       { 
        if (Model == null) 
        { 
         Model = new ImageCollectionModel(); 
        } 
        Model.Collection.Clear(); 
        Model.Collection.AddRange(Collection); 
        Model.Save(file); 
       } 
      } 
     }); 
     Cancel = new DelegateCommand(() => 
     { 
      Collection.Clear(); 
      if (Model != null) 
      { 
       foreach (var item in Model.Collection) 
       { 
        Collection.Add(item); 
       } 
      } 
     }); 
     Browse = new DelegateCommand(() => 
     { 
      var open = new Microsoft.Win32.OpenFileDialog(); 
      if (open.ShowDialog() ?? false) 
      { 
       NewUri = open.FileName; 
      } 
     }); 
    } 
    public ImageCollectionModel Model { get; set; } 
    public ObservableCollection<ImageModel> Collection { get; } = new ObservableCollection<ImageModel>(); 

    private string _NewText; 

    public string NewText 
    { 
     get { return _NewText; } 
     set { SetProperty(ref _NewText, value); } 
    } 

    private string _NewUri; 

    public string NewUri 
    { 
     get { return _NewUri; } 
     set { SetProperty(ref _NewUri, value); } 
    } 

    public DelegateCommand Add { get; } 
    public DelegateCommand<ImageModel> Delete { get; } 
    public DelegateCommand Browse { get; } 
    public DelegateCommand Load { get; } 
    public DelegateCommand Save { get; } 
    public DelegateCommand Cancel { get; } 

} 

注意:這個例子使用PRISM和c#6.0