必须确定IPad或者PadView是声明在一个Assembly里面的,而不是简单的将它们的定义Copy到当前的代码当中...
最好还是贴比较完整的代码。

解决方案 »

  1.   

    IPad、AbstractPad和PadView在同一个项目中,编译成一个类库,我想这应该不是问题。我使用Command模式时,对另外一个接口也使用了同样的方法,结果是正确的。这与类的设计有关吗?这是比较完整的源代码:public interface IPadContent:IDisposable
    {
    /// <summary>
    /// 返回标题
    /// </summary>
    string Title
    {
    get;
    } /// <summary>
    /// 返回图标
    /// </summary>
    Bitmap Icon
    {
    get;
    } /// <summary>
    /// 包含的控件
    /// </summary>
    Control Control
    {
    get;
    } /// <summary>
    /// 重新绘制
    /// </summary>
    void RedrawContent();

    /// <summary>
    /// 标题改变时响应此事件
    /// </summary>
    event EventHandler TitleChanged;

    /// <summary>
    /// 图标改变时响应此事件
    /// </summary>
    event EventHandler IconChanged;
    }public abstract class AbstractPadContent:IPadContent
    {
    /// <summary>
    /// 标题
    /// </summary>
    string title;   /// <summary>
    /// 图标
    /// </summary> Bitmap icon;
    /// <summary>
    /// 包含的控件
    /// </summary>
    public abstract Control Control
    {
    get;
    } /// <summary>
    /// 标题
    /// </summary>
    public virtual string Title
    {
    get
    {
    return title;
    }
    }
    /// <summary>
    /// 图标
    /// </summary>
    public virtual Bitmap Icon
    {
    get
    {
    return icon;
    }
    } /// <summary>
    /// 没有图标的构造函数
    /// </summary>
    /// <param name="Title"></param>
    public AbstractPadContent(string Title):this(Title,null)
    {
    }

    /// <summary>
    /// 用标题和图标构造
    /// </summary>
    /// <param name="Title"></param>
    /// <param name="iconResourceName"></param>
    public AbstractPadContent(string Title,string iconResourceName)
    {
    this.title=Title;
    if (iconResourceName!=null)
    {
    this.icon=null; }
    } /// <summary>
    /// 重绘导航条
    /// </summary>
    public virtual void RedrawContent()
    {
    }

    /// <summary>
    /// 卸载资源
    /// </summary>
    public virtual void  Dispose()
    {
    if (icon!=null)
    {
    icon.Dispose();
    }
    } /// <summary>
    /// 标题改变事件
    /// </summary>
    /// <param name="e"></param>
    protected virtual void OnTitleChanged(EventArgs e)
    {
    if (TitleChanged!=null)
    {
    TitleChanged(this,e);
    }
    }

    /// <summary>
    /// 图标改变事件
    /// </summary>
    /// <param name="e"></param>
    protected virtual void onIconChanged(EventArgs e )
    {
    if (IconChanged!=null)
    {
    IconChanged(this,e);
    }
    } public event EventHandler TitleChanged;
    public event EventHandler IconChanged;
    }
    }
    public class PropertyPad : AbstractPadContent
    {

    private static PropertyGrid        grid = null;
    private static IDesignerHost host = null;
    public override  Control Control 
    {
    get 
    {
    return grid;
    }
    }

    public PropertyPad() :base("属性",null)
    {
    grid = new PropertyGrid();
    grid.PropertyValueChanged += new PropertyValueChangedEventHandler(PropertyChanged);
    }

    public static void SetDesignableObject(object obj)
    {
    grid.SelectedObjects = null;
    grid.SelectedObject  = obj;
    }

    public static void SetDesignerHost(IDesignerHost host)
    {
    PropertyPad.host = host;
    ISelectionService selectionService = (ISelectionService)host.GetService(typeof(ISelectionService));

    if (selectionService != null) 
    {
    selectionService.SelectionChanging += new EventHandler(SelectionChangingHandler);
    selectionService.SelectionChanged  += new EventHandler(SelectionChangedHandler);
    }
    }

    public static void SelectionChangingHandler(object sender, EventArgs args)
    {
    } public static void SelectionChangedHandler(object sender, EventArgs args)
    {
    ISelectionService selectionService = sender as ISelectionService;

    if (selectionService != null) 
    {
    ICollection selection = selectionService.GetSelectedComponents();
    if (selection.Count > 0) 
    {
    object[] selArray = new object[selection.Count];
    selection.CopyTo(selArray, 0);
    grid.SelectedObjects = selArray;

    else 
    {
    grid.SelectedObjects = new object[0];
    grid.SelectedObject = null;
    }
    }
    }

    void PropertyChanged(object sender, PropertyValueChangedEventArgs e)
    {
    if (host != null) 
    {
    DesignerTransaction transaction = host.CreateTransaction("属性改变了");
    transaction.Commit();
    }
    }
    }
      

  2.   

    我使用Assembly创建对象后,查看其Type,返回的是"PropertyPad",也就是正确结果,但是就是不能将其转换成 IPadContent。我试着写了一个简单一点的类从IPadContent继承,但是还是
    有问题。这是怎么回事?是我的接口定义有问题吗?
      

  3.   

    fourfire29,为什么不能直接调用?
    我在做菜单命令时使用了Command模式,也有这样的转换,运行正常,只不过接口定义得比较简单。还有,用反射好像只能解决创建对象的问题,不能解决这样从类到接口的强制转换问题吧?
    感觉有点势单力孤,希望大家多出点意见。
      

  4.   

    我使用“aPadView= Assembly.GetCallingAssembly().CreateInstance("PadView")” 方式创建PadView对象后,不能使用 “(IPad) content=(IPad)  aPadView”进行转换,触发“System.InvalidCastException”例外。使用 "as"得到的结果是null。
    其中
    (IPad) content=(IPad)  aPadView
    里面的 content变量是什么类型的?content和aPadView都要强制转化为IPad接口类型,是其中哪一个抛出异常??我写过类似的代码,没遇到这种问题。
      

  5.   

    content为一新定义的接口对象,在将aPadView对象由一个PadView转换为IPad接口时抛出异常。我具体的语法是这样的:IPadContent[] contents = (IPadContent[])(AddInTreeSingleton.AddInTree.GetTreeNode(viewContentPath).BuildChildItems(this)).ToArray(typeof(IPadContent));

    foreach (IPadContent content in contents) 
    {
      
    ShowPad(content);
    }其功能是,我将一组要处理的类保存在XML文件中的某个结点下,使用[(AddInTreeSingleton.AddInTree.GetTreeNode(viewContentPath).BuildChildItems(this)创建该结点下具体的对象,创建后以数组方式返回,并将其转换成接口类型。但是在转换时,抛出异常了。我检查过了,创建的对象是正确的,其type是ViewPad,但是就是不能转换成接口。
    真是郁闷啊。