我可以从WPF ComboBox序列化和反序列化DataRowView吗?

时间:2016-05-23 07:59:38

标签: wpf serialization combobox

我在代码隐藏中使用包含列" Listkey"的数据表来填充WPF组合框的项目源。和" Listvalue"那样:

SetElementProperty(element, "ItemsSource", (new ListtablesRead()).ReadListtable(changeTextProperties.SelectedListTable).DefaultView);
SetElementProperty(element, "DisplayMemberPath", "Listvalue");
SetElementProperty(element, "SelectedValuePath", "Listkey");

SetElementProperty是一个通过反射检查的方法,如果frameworkelement(在这种情况下是组合框)具有给定属性并设置它。

然后我想用XmlWriter序列化控件。 所以我为DataRowView类型写了一个转换器类:

using System;
using System.ComponentModel;
using System.Data;
using System.Windows;
using System.Windows.Markup;

namespace WPFDesignerConverterLibrary
{
    public class DataRowViewConverter : ExpressionConverter
    {
        /// <summary>
        /// Finds out if the converter can convert an expression-object to the given destinationtype.
        /// </summary>
        /// <param name="context">An ITypeDescriptorContext-interface which provides a context for formatting.</param>
        /// <param name="destinationType">A type-class which represents the target-type of the conversion.</param>
        /// <returns>Returns an object of type bool. True = the destinationtype can be converted.</returns>
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(MarkupExtension))
                return true;

            return false;
        }

        /// <summary>
        /// Converts the expression to the given destinationtype.
        /// </summary>
        /// <param name="context">An ITypeDescriptorContext-interface which provides a context for formatting.</param>
        /// <param name="culture">The System.Globalization.CultureInfo which is actually used as culture.</param>
        /// <param name="value">The object to convert.</param>
        /// <param name="destinationType">A type-class which represents the target-type of the conversion.</param>
        /// <returns></returns>
        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value,
            Type destinationType)
        {
            if (destinationType == typeof(MarkupExtension))
            {
                DataRowView datarowview = value as DataRowView;
                if (datarowview == null)
                    throw new Exception();
                return datarowview.Row;
            }

            return base.ConvertTo(context, culture, value, destinationType);
        }
    }
}

此转换器在序列化XML中工作并生成以下行:

  <sd:DataRow RowError="">
    <sd:DataRow.ItemArray>
      <x:Array Type="s:Object" xml:space="preserve"><s:String>01</s:String><s:String>Ersttest                      </s:String></x:Array>
    </sd:DataRow.ItemArray>
  </sd:DataRow>
  <sd:DataRow RowError="">
    <sd:DataRow.ItemArray>
      <x:Array Type="s:Object" xml:space="preserve"><s:String>02</s:String><s:String>Wiederholungstest             </s:String></x:Array>
    </sd:DataRow.ItemArray>
  </sd:DataRow>
  <sd:DataRow RowError="">
    <sd:DataRow.ItemArray>
      <x:Array Type="s:Object" xml:space="preserve"><s:String>03</s:String><s:String>Konstanzprüfung               </s:String></x:Array>
    </sd:DataRow.ItemArray>
  </sd:DataRow>

但是当我尝试重新加载序列化的XML时,我收到一条错误消息,其中说没有找到DataRow类型的标准构造函数。 出了什么问题? 更进一步:使用数据表的默认视图设置组合框的项目源是最简单的方法,但是我必须采取另一种方式吗?

的InnerException:        = -2146233069 HResult        消息=对于类型&#34;系统。数据。的DataRow&#34;没有找到标准构造函数。可以使用参数或FactoryMethod指令提供类型。        来源=系统。 XAML        堆栈跟踪:             在系统。 XAML。图案。 XamlTypeInvoker。 DefaultCtorXamlActivator。 EnsureConstructorDelegate(XamlTypeInvoker类型)             在系统。 XAML。图案。 XamlTypeInvoker。 CreateInstance(参数的Object [])             在MS.Internal。 XAML。运行。 ClrObjectRuntime。 CreateInstanceWithCtor(XamlType xamlType,Object [] args)             在MS.Internal。 XAML。运行。 ClrObjectRuntime。 CreateInstance(XamlType xamlType,Object [] args)

2 个答案:

答案 0 :(得分:0)

与此同时,我找到了另一种方式。 我使用名为KeyAndValue的虚拟类:

/// <summary>
/// Dummy class with key and value properties for construction of comboboxitems.
/// </summary>
public class KeyAndValue
{
    /// <summary>
    /// Gets or sets the key.
    /// </summary>
    public string Key { get; set; }

    /// <summary>
    /// Gets or sets the value.
    /// </summary>
    public string Value { get; set; }
}

该课程有助于填充组合框的项目集合:

    foreach (System.Data.DataRow row in table.Rows)
    {
        // Add new pairs with Listkey and Listvalue as content to the Items-collection.
        customComboBox.Items.Add(new KeyAndValue() { Key = row["Listkey"].ToString(), Value = row["Listvalue"].ToString() });
    }

这有点像使用一个差异的KeyValuePair:像KeyValuePair这样的通用列表无法序列化。 但我的假班做了。

答案 1 :(得分:0)

您需要的是拥有一个无参数的contrsuctor(Default Constructor}的课程,允许Serialization
步骤1。 创建class以保存数据库结果。

  • 您可以通过手动代码执行此操作,也可以使用DataSet

步骤2.
创建类或使用数据集序列化后。

FileStream fs = new FileStream(savePath + "\\" + a.Location + ".bin", FileMode.Create);
BinaryFormatter serializer = new BinaryFormatter();
try
{
    serializer.Serialize(fs, a);
}
catch (Exception e)
{
    //handle your fail;
}
finally
{
    fs.Close();
}  

或反序列化:

List<Model.YOURCLASS> _l = new List<Model.YOURCLASS>();
string[] files = Directory.GetFiles(pathToSearch);
FileStream fs;
BinaryFormatter deserializer = new BinaryFormatter();
foreach (var a in files)
{
    if(Path.GetExtension(a) == ".bin")
    {
        fs = new FileStream(a, FileMode.Open);
        _l.Add((Model.YOURCLASS)deserializer.Deserialize(fs));
    }
}
return _l;  

您的例程返回的类型不一定是DataTableListView会自动使用您传递的任何集合,即使是array[]