1

メソッド GetData() が Type のパラメーターを必要とする理由がわかりません。Type は、オブジェクトがどのクラス/タイプであるべきかを指定するものだと思いました。GraphicsPathWrap という構造があり、ISerializable を実装することでシリアライズ可能になります。次のコピー機能を試しました。

private void Copy(GraphicsPathWrap gpw){
  DataObject obj = new DataObject();
  obj.SetData(typeof(GraphicsPathWrap), gpw);
  Clipboard.SetDataObject(obj);
}

次に、次の貼り付け機能を試しました。

private GraphicsPathWrap Paste()
{
  return (GraphicsPathWrap)Clipboard.GetDataObject().GetData(typeof   (GraphicsPathWrap));
}

動作するはずですが、GetData(...) は MemoryStream 型のオブジェクトを返し、InvalidCastException がスローされました。なぜそれがMemoryStreamのタイプなのかわかりません。GraphicsPathWrap にキャストできるはずだと思いましたか? BinaryFormatter を使用して MemoryStream を逆シリアル化することでこれを回避できますが、クリップボードがすべてのことを実行できない場合はばかげていますか?

ありがとう!

4

4 に答える 4

2

編集:私はあなたの状況を正確にシミュレートしました。ISerializable インターフェイスを実装し、適切に逆シリアル化していないときに MemoryStream と言っていたのです。

GetData() は、以下のシナリオでメモリ ストリームを返します。

      [Serializable]
        public struct GraphicsPathWrap : ISerializable
        {
            private static string myValue = "This is the value of the class";             

            // Creates a property to retrieve or set the value. 
            public string MyObjectValue
            {
                get
                {
                    return myValue;
                }
                set
                {
                    myValue = value;
                }
            }

            #region ISerializable Members

            public void GetObjectData(SerializationInfo info, StreamingContext context)
            {

            }

            #endregion
        } 

次に、GetData() が正しい型オブジェクトを与えるときに、シリアライゼーション\デシリアライゼーションを適切に実装しました。

[Serializable]
        public struct GraphicsPathWrap : ISerializable
        {
            private static string myValue = "This is the value of the class";

            public GraphicsPathWrap(SerializationInfo info, StreamingContext ctxt)  // Deserialization Constructor
            {
                myValue = (string)info.GetValue("MyValue", typeof(string));
            }

            // Creates a property to retrieve or set the value. 
            public string MyObjectValue
            {
                get
                {
                    return myValue;
                }
                set
                {
                    myValue = value;
                }
            }

            #region ISerializable Members

            public void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                info.AddValue("MyValue", myValue); // Serialize the value
            }

            #endregion
        }

上記の回答がお役に立てば幸いです

于 2013-03-09T08:55:36.413 に答える
1

Clipboard.SetDataObject(object data) メソッド名は、パラメーターとして DataObject を具体的に要求するのではなく、Serializable である必要があるオブジェクトだけを要求しているため、少し誤解を招く可能性があります。

次のように gpw を直接渡してみることができます。

private void Copy(GraphicsPathWrap gpw){
  Clipboard.SetDataObject(gpw);
}

GraphicsPathWrap がシリアライズ可能な場合は機能するはずです。

編集: 自分自身をテストした後、このメソッドは、Serializable オブジェクトを直接渡すか、DataObject にカプセル化するかのいずれかの方法で機能することがわかりました。その特定のクリップボード メソッドの .Net ソース コードをチェックして確認しました。

if (data is DataObject) 
{
      dataObject = (DataObject)data; 
}

そのため、Ramesh が他の回答で述べているように、オブジェクトが適切にシリアライズ可能に設定されているかどうかを確認することをお勧めします。

于 2013-03-09T08:44:17.363 に答える
0
[DataObject(true)]
    public class EmployeeDAL
    {
        [DataObjectMethod(DataObjectMethodType.Update, true)]
        public int UpdateEmployeeSalary(int percentage, int deptid, int posid)
        {
            OracleConnection con = new OracleConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
            OracleCommand cmd = new OracleCommand("GIVE_RAISE_SP", con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("PV_PERCENTAGE_RAISE_I", OracleType.Int32).Value = percentage;
            cmd.Parameters.AddWithValue("PV_POSITIONID_I", OracleType.Int32).Value = posid;
stac            cmd.Parameters.AddWithValue("PV_DEPTID_I", OracleType.Int32).Value = deptid;
            cmd.Parameters.AddWithValue("PV_NUM_EMPLOYEES_O", OracleType.Int32).Direction = ParameterDirection.Output;

            OracleDataAdapter da = new OracleDataAdapter(cmd);

            try
            {
                con.Open();
                da.UpdateCommand = cmd;
                cmd.ExecuteNonQuery();
            }
            catch (Exception)
            {

            }
            finally
            {
                con.Close();
            }

            return Convert.ToInt32(cmd.Parameters["PV_NUM_EMPLOYEES_O"].Value);
        }
于 2016-04-21T00:50:59.607 に答える