How to remove alt style from chart component in c#.net? - asp.net

I have a stacked chart component (from the MS Chart Control Library) on a c#.net webform which I created by dragging the control onto the design surface. I then edited the source html (.aspx page) to give the element a css class and remove the style attribute that was there originally. This was so that I could control the style from the css file instead of using embedded styling. Here is the html:
<asp:Chart ID="Chart1" runat="server" DataSourceID="SqlDataSource1" CssClass="smallBarChart"
IsMapAreaAttributesEncoded="True">
In the site.css file, I have specified the following:
.smallBarChart
{
width: 350px;
height: 230px;
}
When I run the web-app, the html that is rendered for the chart component has an "alt style" attribute added in. Even though it has the correct class attribute it is using the information contained in the "style" attribute. Why is this "style" attribute being generated by .net??. I have taken all style attribute info out of the original aspx file.
I don't have any instructions to change the style in my code behind (.cs) file
<img id="Chart1" class="smallBarChart" src="/Charts/ChartImg.axd?i=chart_2c39400223fb4933bf5a99e05d6119d4_3.png&g=b5c73578558442d3b9e1dd54cc127f20" alt="" style="height:300px;width:300px;border-width:0px;">
I should emphasise that I need to control the style of the chart component from my site.css file so any suggestions around using inline styling are not an option for me. Inline styling (adding a style attribute to a html element) is bad practice in any case!!!

I don't know why ASP.NET is overriding your work, but try this in your CSS:
.smallBarChart
{
width: 350px !important;
height: 230px !important;
}
Good Luck!

Set your chart's dimensions (Width/Height) at design time:
<asp:Chart Height="Unit" Width="Unit" ID="Chart1" runat="server" DataSourceID="SqlDataSource1" CssClass="smallBarChart" IsMapAreaAttributesEncoded="True">

Im beginning to think the answer to this is that because the .net runtime generates the html necessary to build the chart at runtime and because it transforms "Chart1" from an element into an element so that the browser can understand it, it will insert its own style attributes at runtime (even if I remove this in the .aspx file, the properties window shows 300px x 300px by default).
This being the case, it seems pointless assign a cssClass to the control since any matched CSS rule will be overridden by the inline style that .net gives the element when the HTML is served up (which is always 300 x 300px in my case for some reason.
In other words, I can not specify the width and height of an asp.net control in a separate css file because asp.net will ALWAYS give it its own style attribute at runtime.
The reason I posted this question is that I want to define the size of what I call a "Small Bar Chart" in the web site's CSS file so that if I have 10, 15 or 20 of these small barcharts on a page, I can resize them all. I guess the way to do this in .net is to create a custom control that is the right size since it wont let you control its style from a CSS file.

I encountered a similar problem using .net chart control and Zurb foundation, and we want our image to scale in a responsive layout. Zurb does a great job of that but really needs no width or height set on the image.
Unfortunately with the width and height are set on the image tag via the style attribute. We found that scaling was only performed on the width of our charts but the height remained the same. So, without proportional scaling our charts could look a little squashed.
Our solution is to subclass the chart control, override the render method, get the base class to render html and then modify the html to remove styles. Doing this allowed the charts to scale themselves proportional to their container.
Here is our solution:
public class ChartWithNoDimensionsSpecified : Chart
{
//we override this because the child chart controls may throw an exception and we don't want that to take down our whole page!
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
try
{
//get the base control to render itself into our stringwriter
System.IO.StringWriter stringWriter = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter chartWriter = new System.Web.UI.HtmlTextWriter(stringWriter);
base.Render(chartWriter);
//get the html rendered and find the start and end of the style tag
//note we assume no spaces between the style attribute = and "
//we also assume the img tag is first and there are no tags before it with a style
string html = stringWriter.ToString();
int pos = html.IndexOf("style=\"",StringComparison.OrdinalIgnoreCase);
if (pos != -1)
{
int pos2 = html.IndexOf("\"", pos + 8);
//we only want this one style to be set in the tag itself.
string replaceStyleAttr = "border:0px;";
//write the image tag, excluding the existing styles but replaced with our own...
writer.Write(html.Substring(0, pos + 7) + replaceStyleAttr + html.Substring(pos2));
}
else //incase we could not find the style tag...
{
//write out the existing standard html. We could alternatively throw an error here.
writer.Write(html);
}
}
catch (Exception ex)
{
//if there is an error, write this output instead
writer.Write("<div title=\"The chart control could not be rendered. This may be related to configuration, permissions or IIS being confused about access to the temp chart images folder (exception: " + HttpUtility.HtmlAttributeEncode(ex.Message) + "). If the charts have otherwise worked ok, recycle the IIS app pool and stop/start the site\"><span style=\"color:#ff0000;\">Error</span> (hover for detail)</div>");
}
}
}
In our case the charts are generated grammatically in c# code, and so we don't use the asp.net designer. If you do, you may need to make some changes to this to use that in the designer.

Related

Custom image class rendering method

I wish to change img tag inside some Page template element to another tag. It's necessary to use parallax effect for each image on page (without specific class or created in CMS). Because Images cannot be styled, I decided to replace img tag with another. I can do this using JS, so poor browser won't be affected, but decided to ask could it be done by PHP and silverstripe?
In response to Conny Nyman's text. There an example JS code.
var el = document.querySelectorAll('.Paralax'); // Obtain images to which should been paralax effect apply
for (i = 0; i < el.length; ++i) {
// Create more elements, for example parent of div created bellow, so browser will properly calculates height - or use getComputedElementStyle from image element and apply result to nel
var nel = document.createElement('div');
nel.style.background = 'url("' + el[i].getAttribute('src') + '")';
el[i].parentNode.insertBefore(nel, el[i]);
el[i].parentNode.removeChild(el[i]);
}
Above code will do this, by using JS. I realize I need to not use JS, but add server support. Because Page was generated by many templates and I need allow to add paralax image from CMS, I need a way to add global template for all img tag, which checks only img have Paralax class.

Custom CSS Class for dijit/layout/ContentPane

I want to add a custom CSS Class to a dijit/layout/ContentPane so I'm able to style it myself.
This is cause I got more than one tab in my TabContainer where my ContentPanes are located and I don't want to double the borders. Using a border all around the Tab will double the border so I removed the left border of the tabs. In the first tab in the TabContainer I need the left border, too.
To get this I tried to assume the first ContentPane a custom CSS class which will do it.
As you see me writing here, I didn't find a way to do this.
I tried it within the data-dojo-props with
<div data-dojo-type="dijit/layout/ContentPane" title="FunnyTitle" data-dojo-props="class:'firstTab'">
So this didn't work. I tried to add it like I do it in a simple HTML element with class="firstTab"
<div data-dojo-type="dijit/layout/ContentPane" title="FunnyTitle" class="firstTab">
Both ways didn't add my class to the ContentPane.
So how is it done?
The class property is actually not used for that kind of purpose, but it used for identifying of which type the widget is.
However, the class attribute should work, because declarative widgets usually keep their parent attributes. If I have the following HTML:
It eventually gets rendered into:
<div class="dijitContentPane test" data-dojo-type="dijit/layout/ContentPane" id="myContent" widgetid="myContent">
Hello
</div>
However, please note that when using a dijit/layout/ContentPane inside a dijit/layout/TabContainer a lot of additional CSS is added, possibily overriding your own CSS.
For example, for overriding the background color of a tab inside a dijit/layout/TabContainer, I had to use the following CSS selector:
.dijitTabContainerTop-dijitContentPane.test2 {
background-color: #D4D4D1;
}
Demo: http://jsfiddle.net/Lcog9saj/
But also, be aware that the borders generated by the TabContainer are not applied to the ContentPane itself, but to an element with classname .dijitTabContainerTop-container (part of the TabContainer itself).
If this really doesn't work, then you can always access the domNode property of the widget you're trying to alter, for example:
require(["dijit/registry", "dojo/ready", "dojo/dom-class"], function(registry, ready, domClass) {
ready(function() {
domClass.add(registry
.byId("myContentPane")
.get("domNode"), "test2");
});
});
It's that simple that I didn't get it.
All you need to do is adding an ID to the ContentPane.
Dojo generates a widgetID with it like "dijit_layout_TabContainer_0_tablist_myID"
If the TabContainer itself has an ID, it could be different. Just have a look at the generated code.
Now you're able to get it with dijit.byId.
At the end it looks something like:
var tab = dijit.byId("dijit_layout_TabContainer_0_tablist_myID");
domClass.add(tab.domNode,"myClassName");
domClass is a part of dojo. For using it you just need to require it "dojo/dom-class"

CssClass and default images in ServerContol

I'm writing a ServerControl in ASP.NET 3.5, and I'm exposing CssClass, so the user can manipulate the visual appearance of the control. My problem is that I want to establish reasonable defaults, so that the user doesn't have to configure CSS unless he wants to change the defaults.
My specific problem is that my control is emitting html divs, that need to display background images. I want the user to be able to specify a different image in CSS, but I want to display a default background image, and I can't make that work.
The entire server control is emitted as a div, with a class name set to the value the user provided in CssClass. The div that needs the background image is enclosed within this outer div, with a class name of its own. I am currently setting the background image in CSS on the page that contains the control:
<style type="text/css">
.cssClass .innerDiv {
background-image: url("http://....");
}
</style>
With this the proper image is drawn. But if it's not there, no image is drawn.
What I want is for the ServerControl to emit some CSS that will define these image urls, that would be over-ridden by any css that was added by the user, and for that default CSS to include URLs to images embedded in the ServerControl's assembly.
And I'm not sure of how to do either. Nor, for that matter, am I sure this is the best approach.
Any ideas?
Expose various properties with CSS classes, such as HeaderCssClass, ItemCssClass, if you need more than one style.
Also, you can do a check that if the user has a CSS class name specified, you use that; otherwise, use your default and omit the custom CSS from the control.
In your rendering logic, you can render the right CSS class name as the attribute of the DIV depending on whether the user has specified anything. So you can do:
if (this.HeaderCssClass != null)
writer.AddAttribute("class", this.HeaderCssClass);
else
writer.AddAttribute("class", "standard");
writer.RenderBeginTag("div");
And only write out your standard CSS if the HeaderCssClass is null.

ASP.NET Theme stylesheet rendering

When a page with theme is rendered, the stylesheets link tags in the given theme are rendered right before the closing head tag. Does anyone know of a way to change that? Is there a way that I could have those tags be placed right after the opening head tag?
I know it can be down with jquery by just selecting all the link tags and placing it right after the opening head tag, but is there a way to set it on the server end?
Clarification
Let us say I have a single css file (themed.css) in my theme. In that css file, I have a single style definition for a div tag with an id of test:
#test {background-color:red; color:white;}
Let us also say I have a second css file (standard.css) that is NOT in my theme, but it has another definition of the div tag with an id of test:
#test {background-color:yellow;}
I have my page to use the theme, and I have a handwritten link tag to use standard.css. When the page is executed, the link tag for standard.css is before themed.css. When that happens my div tag with id of test has a red background and white forecolor. If I want the themed.css to apply and then standard.css to overwrite the necessary properties (yellow background with white forecolor), I would want themed.css and THEN standard.css. I can't do that because ASP.NET places the theme files right before the closing head tag.
I don't want to have to know that my theme's css files are the nth link tag in my head tag and then manual change any index whenever i may add a new css file outside of my theme.
Thanks!
I did a little checking in Reflector, and found something you may find interesting. The framework calls the SetStyleSheet method of a PageTheme-derived object to inject link controls in the header. This code snippet shows the relevant logic:
int num = 0;
foreach (string str in this.LinkedStyleSheets)
{
HtmlLink child = new HtmlLink { Href = str };
child.Attributes["type"] = "text/css";
child.Attributes["rel"] = "stylesheet";
if (this._styleSheetTheme)
this.Page.Header.Controls.AddAt(num++, child);
else
this.Page.Header.Controls.Add(child);
}
Translation? StyleSheetThemes inject the style sheets at the beginning of the header tag, and Themes inject the style sheets at the end.
This is consistent with the intended difference between themes and stylesheet themes; that is, that a theme always wins when there is a conflict between the skin and the control settings. Sure, a style in a non-themed .CSS file using the !important attribute could still override a theme style, but the positioning of the CSS files within the head tag strategically facilitates override-ability stylesheet themes.
Note that you can have both a stylesheet theme and a regular theme. Naturally, leave to the stylesheet theme things you design to be override-able, and to the theme things that should not be overridden.
One final observation is that the method is internal and non-virtual, so interfering with these two options would take some kung-fu-MMA-mad-reflection skills, and is probably not in the best interest of stability or maintainability.
As soon as your head element has runat="server" you can rearrange the collection in Page_PreRender:
protected void Page_PreRender(object sender, EventArgs e)
{
ControlCollection container = this.Page.Header.Controls;
foreach (var control in container.OfType<System.Web.UI.HtmlControls.HtmlLink>().ToArray())
{
container.Remove(control);
container.AddAt(0, control);
}
}

Skins and Stylesheet noob question

I have a Skin File that contains:
< asp:TextBox runat="server" CssClass="FixedFont"/>
In the same folder as the Skin file, is the following css file. The Css file contains:
.FixedFont
{
font-family:Courier;
}
Lastly, I have an ASPX page which contains the following control:
<asp:TextBox ID="TextBox1" runat="server">Test</asp:TextBox>
When I view the ASPX page in design mode or run the page, I see that the font-family attribute on the style does effect the textbox control, namely, it is changed to Courier.
However, what I would also like to do is to define a local style on my ASPX page,
.DefaultWidth
{
width: 300px;
}
...and have all of my TextBoxes so that they are the same width.
If I set the CssClass property of TextBox1 to "DefaultWidth"...
<asp:textbox ID="TextBox1" CssClass="DefaultWidth">Hello</asp:TextBox>
...the width of the textbox is changed to 300px but I lose the effect of the skin appling the fix font Courier style.
To get BOTH effects to be applied, the DefaultWidth and the fixed font textbox effect, I have to set the CSSClass property to "DefaultWidth FixedFont", which to me, seems like it defeats the advantage of having the skin in the first place. I guess I expected the effect to be CUMULATIVE, unless I added a style that conflicted with the SKIN, in which case, I expected the local class to be applied over the skin's effect. For example, If I applied a second class, Class2, that also included a font-family specification in addition to other effects, I would expect the font specified in Class2 to override that in the FixedFont style. But that doesn't appear to be what is going on here.
What is the best way to manage such a situation? I imagine very often wanting to have a series of textboxes that all match in width, so I imagine that I will very often want to specify a CssClass on a control in addition to using the effects applied to the control in type in the skin file.
Is the solution NOT to use CSS in the SKIN itself? This seem like it has disadvantages, too, on the side of maintenance.
A secondary problem that I am having is that if I declare a stylesheet with the following class..
.Button
{
background-image: url('/images/button.gif')
}
...and set the CSSClass property of an ASP Button to "Button", I see the image tiled over the button.
However, if I enter the following code in the skin file
it does not find the image.
The images folder is a first-levl folder off of the root of the website.
Any idea why it is not picking up the image. I;'ve tried various other paths, but that is the only one that seems to make sense to me.
By the way, the image is applied in design mode, but it disappears when ity is run.
I don't know if I understood your question but as I'm seeing from here, what you should have to declare this in your "local" style:
textbox.fixedfont { width:200px; }
or simply to every textbox if you are sure about affecting every textbox with the same width, doesn't matter the skin...
textbox { width:200px; }
If this not what you were asking for, please be clearer.

Resources