Redefining default style

Oct 8, 2012 at 1:26 PM

Hi,

What is the best way to redefine the default style of a Shape inherited from some standard Shape? The following code seems ugly:

protected override void InitializeToDefault(IStyleSet styleSet)
{
    base.InitializeToDefault(styleSet);
    FillStyle fs = styleSet.FillStyles.Green as FillStyle; // " = new FillStyle();" leads to an error :((
    fs.BaseColorStyle = new ColorStyle("LightGreen", Color.LightGreen);
    fs.FillMode = Dataweb.NShape.FillMode.Solid;
    FillStyle = fs;
}

What I need is to change "gradient blue" to "solid lightgreen".

Do I need to create FillStyle object each time or it's better to cache it somewhere? And why using the commented code gives an error "The given key was not present in the dictionary" in Dataweb.NShape.StyleCollection`1.GetPreviewStyle(String styleName)?

Coordinator
Oct 9, 2012 at 9:14 AM
Edited Oct 9, 2012 at 9:46 AM

First, let me explain the issues you ran into:

Styles are managed in the Project's Design. If you want to define new styles with code, you have to add the new styles to the design first and afterwards, you can use it. In addition to that, the styles name property should not be empty because it's used as indexer key (e.g. IFillStyle s = Design.FillStyles["NameOfStyle"]; ).
Example:

// First, define the required color style "LightGreen"
ColorStyle colorStyle = new ColorStyle("MyLightGreen", Color.LightGreen, 0);
// Use Design.AddStyle method because it creates a "preview style" (transparent grayscale 
// style for drawing previews) automatically
project.Design.AddStyle(colorStyle);

FillStyle solidGreen = new FillStyle("LightGreen Solid");
solidGreen.BaseColorStyle = project.Design.ColorStyles["MyLightGreen"]; 
solidGreen.FillMode = FillMode.Solid; 
// You can also use StyleCollection.Add instead of Design.AddStyle but you have to create 
// the "preview style" manually in this case 
project.Design.FillStyles.Add(solidGreen, project.Design.CreatePreviewStyle(solidGreen)); 

 

After adding the fill style, you can use it in shapes:

myShape.FillStyle = project.Design.FillStyles["LightGreen Solid"];

 

This will work but I would disadvise this solution because you will never be able to use this shape library in any program that does not create a fill style called "LightGreen Solid" on startup (e.g. NShape Designer).

The recommended solution would be to create a new Template (or modify the existing) for your shapes. You can save the changes and load this project every time your project starts or perform this in code (see documentation: "Programmer Tasks > Customizing the Toolbox > Loading a Template Project" and "Programmer Tasks > Customizing the Toolbox > Filling the Toolbox Manually").
Afterwards, use the templates for shape creation:

If you do not like this solution, change the standard FillStyle "Green" to solid light green and use if in the InitializeToDefault method of your shape:

private void Form1_Load(object sender, EventArgs e) {
	// ...		
	project.Design.FillStyles["Green"].BaseColorStyle = project.Design.ColorStyles["LightGreen"];
	project.Design.FillStyles["Green"].FillMode = FillMode.Solid;
	project.Repository.Update(project.Design);
}


protected override void InitializeToDefault(IStyleSet styleSet) {
	base.InitializeToDefault(styleSet);
	FillStyle = styleSet.FillStyles.Green;
}

 

Shape s = project.Repository.GetTemplate("Box").CreateShape();
Oct 9, 2012 at 12:35 PM

Thank you very much for such a detailed answer.

As far as my shape library will be used only in one application, the 1st approach is fine. However, I can't make it work. If I place your code before call to myForm1.project1.Create(), then your code produces error "Project must be open to execute this operation"; if after - then your code is not executed at all because myForm1.project1.Create() fails with error "The given key was not present in the dictionary" (the key mentioned here is the style name, i.e. "LightGreen Solid").

Could you please tell what is the right place for your code?

Coordinator
Oct 9, 2012 at 12:51 PM
  1. Call project.Create with no (or only standard) libraries
  2. Modify your project's Design and update the repository
  3. Load your shape library
Oct 9, 2012 at 1:02 PM

Thank you - works like a charm! I'm really happy that I'm not limited to built-in styles anymore. Maybe if I have more time for research I'll try the recommended approach with Templates; currently I'm not very good with the Template concept :)