views:

218

answers:

1

I get "Error rendering control" error that only happens when I place the control on the webform in desgin-mode, if I run the page the control is displayed correctly.
The above statement is not important, this error happens because the returned toolbars object is null.

After debugging, the problem is in a function that is called from CeateChildControls():

public static ToolBars LoadToolbarsFromConfigFile()
{

      ToolBars toolbars;
      Assembly executingAssembly = Assembly.GetExecutingAssembly();
      string resource = "Editor.ConfigFiles.ToolBars.xml";
      using (Stream stream = executingAssembly.GetManifestResourceStream(resource))
      {
            XmlSerializer serializer = new XmlSerializer(typeof(ToolBars));
            toolbars = (serializer.Deserialize(stream)) as ToolBars;

      }
      return toolbars;                
}

the toolbars returns null! (in design-mode)
But when I run the page, toolbars returns appropriate data.

If you need some more info about my code please ask.

Update:

It must be something with Assembly, If I use file stream instead with specified file, it does work.

Another UPDATE:

I've modified my code a bit, and added "dataset" for test purpose:

using (DataSet ds = new DataSet())
{               
    ds.ReadXml(typeof(TheEditor).Assembly.GetManifestResourceStream("Editor.ConfigFiles.ToolBars.xml"));
    //show message box to see if it works
    System.Windows.Forms.MessageBox.Show(ds.Tables.Count.ToString());    
}

Another thing that I noticed, all above happens when I add my control to a new website project, but if I set debug property of control's project to start external program (i start visual studio) , and there I create a new project and add the control everything works.

+2  A: 

When you are running this within Visual Studio, you don't have an Application context, and so you can't "GetExecutingAssembly" on it - or more accurately, the Executing Assembly is devenv.exe, and that doesn't have the resources you're looking for.

You can use the DesignMode property of the control to check and see if you are rendering the control within Visual Studio, and modify your behaviour appropriately:

public static ToolBars LoadToolbarsFromConfigFile()
{
  ToolBars toolbars;
  if (!DesignMode)
  {
    Assembly executingAssembly = Assembly.GetExecutingAssembly();
    string resource = "Editor.ConfigFiles.ToolBars.xml";
    using (Stream stream = executingAssembly.GetManifestResourceStream(resource))
    {
      XmlSerializer serializer = new XmlSerializer(typeof(ToolBars));
      toolbars = (serializer.Deserialize(stream)) as ToolBars;
    }
  }
  else
  {
    // Load a dummy toolbar here.
  }
  return toolbars;                
}

Alternatively, you could perform the check in the calling code, but as this is a public method, there's no guarantee that all callers would perform this check, so you're better off doing it in the method.

A final option would be to create a Designer class that overrides the LoadToolbarsFromConfigFile method and supplies a dummy toolbar for you.

Zhaph - Ben Duguid
wow, bad news.... so there is no way to point designer to the control's assembly to load the resource? I don't like the idea of adding special code for dummy toolbar.
markiz
also hoe can i use dummy toolbar it I need to save it's images in resource as well?
markiz
Well, the "Load dummy toolbar" method could attempt to look at the projects resources, but I think you'd then be adding a lot of code and dependencies to the project that wouldn't necessarily exist on the server - Taking a look at the Telerik controls, they don't display the toolbars on the design surface: http://tv.telerik.com/radtips/radeditor/radeditor-for-asp.net-ajax-+-share-toolbars-using-the-toolproviderid :(
Zhaph - Ben Duguid
But others do: like http://www.codeproject.com/KB/ajax/HtmlEditor.aspx, or http://jiffycms.codeplex.com/ and more
markiz
Fair enough - both of those have their full source available for you to look at, and both of them make extensive use of the DesignMode property to change the behaviour of the control when it's being used in Visual Studio. I notice that the CodeProject one declares all its resources in the top of the class - that probably makes it easier to find them without having to load the Assembly
Zhaph - Ben Duguid
i also define in the top of the class.One note: the problem is only with accessing to XML, I can access images like Page.ClientScript.GetWebResourceUrl(this.GetType(), resource);
markiz