0

RelayCommand の実装に次のイベントがあります。

public event EventHandler CanExecuteChanged
{
  add { CommandManager.RequerySuggested += value; }
  remove { CommandManager.RequerySuggested -= value; }
}

今私は使用してDataContractSerializerいます。DataContractSerializerすべてのイベントを使用する場合は、 としてマークする必要があることを知ってい[field:NonSerialized]ます。しかし、この場合、これは機能しません。なぜなら、私のCanExecuteChangedEvent はプライベート フィールドを持たない単なるプロパティだからです。

このプロパティを としてマークするにはどうすればよいNonSerializableですか?

編集:

RelayCommand クラス全体を次に示します。

[DataContract]
public class RelayCommand : ICommand
{

  [field:NonSerialized]
  readonly Action<object> _execute;

  [field:NonSerialized]
  readonly Predicate<object> _canExecute;

  public RelayCommand(Action<object> execute)
    : this(execute, null)
  {
  }

  public RelayCommand(Action<object> execute, Predicate<object> canExecute)
  {
    if (execute == null)
      throw new ArgumentNullException("execute");

    _execute = execute;
    _canExecute = canExecute;
  }

  [DebuggerStepThrough]
  public bool CanExecute(object parameters)
  {
    return _canExecute == null ? true : _canExecute(parameters);
  }

  public event EventHandler CanExecuteChanged
  {
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
  }

  public void Execute(object parameters)
  {
    _execute(parameters);
  }
}

を実行しようとするとDataContractSerializer、次のエラーが発生します。

データ コントラクト名 'RelayCommand:http://schemas.datacontract.org/2004/07/MyNamespace' で 'MyNamespace.RelayCommand' を入力することは想定されていません。たとえば、KnownTypeAttribute 属性を使用するか、DataContractSerializer に渡される既知の型のリストにそれらを追加することにより、静的に認識されていない型を既知の型のリストに追加します。

4

1 に答える 1

1

それが、コメントで提供されたリンクからサンプルを更新した方法です。

[Serializable]
public abstract class BaseClass
{
    public string Name { get; set; }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
}

public class DerivedClass : BaseClass
{
    public int Age { get; set; }
}


class Program
{
    static void Main(string[] args)
    {
        var derivedClass = new DerivedClass { Name = "Test", Age = 10 };
        derivedClass.CanExecuteChanged += (sender, eventArgs) => Console.WriteLine("hello");

        var serializer = new DataContractSerializer(typeof(DerivedClass));
        using (var stream = new FileStream("d:\\test.txt", FileMode.Create, FileAccess.ReadWrite))
        {
            serializer.WriteObject(stream, derivedClass);
        }
    }
}

例外なく機能します。

于 2012-07-09T08:53:31.767 に答える