HTML Renderer for WPF not rendering correctly - c#

I'm using "HTML Renderer for WPF" from NuGet. I'm finding the output to be inadequate, and the discussion boards seem quiet and unmonitored so I thought it better to post here.
I have an HtmlPanel quite trivially in my xaml as
<htmlrenderer:HtmlPanel Grid.Row="2"
Text="{Binding ReportContent}"/>
where
xmlns:htmlrenderer="clr-namespace:TheArtOfDev.HtmlRenderer.WPF;assembly=HtmlRenderer.WPF"
I'm feeding it some simple HTML;
<!DOCTYPE html>
<html><head><title>dummy</title></head>
<body>
<style>
table {
border-spacing: 5px;
}
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 2px;
}
th {
text-align: left;
}
</style>
<h1>Report for <b>Processing dev</b> generated 16/11/2015 16:02</h1>
<hr/>
<h2>Group <i>Everyone</i></h2>
<table><caption>
<h3><b>Stage 1</b>
Run; Mass start</h3></caption><tr><th>pos</th><th>num</th><th>Name</th><th>Time</th></tr>
<tr><td>1</td><td>1</td><td>Person 1</td><td>00:41:00.0</td></tr>
<tr><td>2</td><td>2</td><td>Person 2</td><td>00:47:23.0</td></tr>
<tr><td>3</td><td>3</td><td>Person 3</td><td>00:47:24.0</td></tr>
<tr><td>4</td><td>4</td><td>Person 4</td><td>00:47:24.1</td></tr>
<tr><td>5</td><td>5</td><td>Person 5</td><td>00:52:00.0</td></tr>
<tr><td>6</td><td>6</td><td>Person 6</td><td>00:54:21.0</td></tr>
<tr><td>7</td><td>7</td><td>Person 7</td><td>00:54:32.0</td></tr>
<tr><td>8</td><td>8</td><td>Person 8</td><td>00:55:04.0</td></tr>
<tr><td>9</td><td>9</td><td>Person 9</td><td>00:56:23.0</td></tr>
<tr><td>10</td><td>10</td><td>Person 10</td><td>01:03:00.0</td></tr>
</table>
<table><caption>
<h3>Overall Results</h3>
</caption><tr><th>pos</th><th>num</th><th>Name</th><th>Time</th></tr>
<tr><td>1</td><td>1</td><td>Person 1</td><td>00:41:00.0</td></tr>
<tr><td>2</td><td>2</td><td>Person 2</td><td>00:47:23.0</td></tr>
<tr><td>3</td><td>3</td><td>Person 3</td><td>00:47:24.0</td></tr>
<tr><td>4</td><td>4</td><td>Person 4</td><td>00:47:24.1</td></tr>
<tr><td>5</td><td>5</td><td>Person 5</td><td>00:52:00.0</td></tr>
<tr><td>6</td><td>6</td><td>Person 6</td><td>00:54:21.0</td></tr>
<tr><td>7</td><td>7</td><td>Person 7</td><td>00:54:32.0</td></tr>
<tr><td>8</td><td>8</td><td>Person 8</td><td>00:55:04.0</td></tr>
<tr><td>9</td><td>9</td><td>Person 9</td><td>00:56:23.0</td></tr>
<tr><td>10</td><td>10</td><td>Person 10</td><td>01:03:00.0</td></tr>
</table>
</body></html>
My app renders this as follows. Note the absence of captions on the tables, the garbage upper left (which only appears when I have captions), and the lack of italic text ("Everyone" should be in italics). Loading this into Chrome renders correctly. I've checked it on validator.w3.org and the only error is the lack of a new "scoped" keyword in the style which isn't generally supported yet anyway.
Does anyone else have experience of this library? Given it doesn't seem to be functioning correctly in such a simple case, and seems like it may be dormant, is it worth persisting with? Is there a simple alternative that can just take a block of HTML and render it rather than what seems the over the top solution of CEFSharp, where various page providers have to be created and registered?

Try System.Windows.Controls.WebBrowser:
<Grid>
<WebBrowser x:Name="webBrowser1" Margin="0" Source="file:///C:/Users/Public/test01.html"/>
</Grid>
Or:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
webBrowser1.Source = new Uri("file:///C:/Users/Public/test01.html");
}

Related

Creating custom SVG Icons in colour and generating the correct HTML with the required classes for the font file

Our company wants me to create a font package with our own custom icons for our Blazor application.
They don't want to reference individual image files as this will mean the browser will have to do multiple https request to fetch each individual file. We are using a menu sidebar with many sub-level items with icons.
Normally, when you create a Black and White SVG icon and generate a font package (lets say on https://icomoon.io/), it will just give you one span tag with one class because it is a black an white icon.
For example:
<span class="icon-BW-View-Customer"></span>
Below is the icon.
When I generate a font package for a colour image, it will create a parent span tag with sub-level span tags with sub-classes.
Now the issue I am trying to resolve is, when I dynamically create the menu items, I need to know if the icon is in colour and how many sub classes it has so that I can loop and add the sub CSS classes and span tags. Is there a way I can check the amount of CSS Query selectors somehow so that I can know how many times my code needs to loop to add these span tags dynamically?
Here is an example of the colour icon I just created for testing purposes with many paths and colours:
This is the CSS classes Icon moon will generate for colour icons:
The issue here is that I need to know how many paths the style.css file contains so that I can build the HTML markup dynamically. (Below this CSS, I have added an example of how they are nested).
.icon-Colour-Icon .path1:before {
content: "\e900";
color: #2e3192;
}
.icon-Colour-Icon .path2:before {
content: "\e901";
color: #be1e2d;
margin-left: -1em;
}
.icon-Colour-Icon .path3:before {
content: "\e902";
color: #00a14b;
margin-left: -1em;
}
.icon-Colour-Icon .path4:before {
content: "\e903";
color: #00a14b;
margin-left: -1em;
}
.icon-Colour-Icon .path5:before {
content: "\e904";
color: #8b5e3c;
margin-left: -1em;
}
.icon-Colour-Icon .path6:before {
content: "\e905";
color: #f9ed32;
margin-left: -1em;
}
Nested Span tags with different path classes:
<span class="icon-Colour-Icon">
<span class="path1"></span>
<span class="path2"></span>
<span class="path3"></span>
<span class="path4"></span>
<span class="path5"></span>
<span class="path6"></span>
</span>
I think your requirements are a little flawed as svg's will be cached after first load.
In answering your question.
Using svg's <use href="" ... :
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol class="bi bi-binoculars" viewBox="0 0 16 16" id="binoculars">
...
</symbol>
<symbol class="bi bi-caret-left" viewBox="0 0 16 16" id="caret-left">
...
</symbol>
</svg>
Razor Component
<svg class="bi" width=#Size height=#Size fill="currentColor" #attributes=#UncapturedAttributes >
<use href="_content/ChatClient.Core/images/bootstrap-icons/application-bootstrap-icons.svg#binoculars" ></use>
</svg>
#code {
[Parameter]
public int Size { get; set; } = 24;
[Parameter(CaptureUnmatchedValues = true)]
public Dictionary<string, object> UncapturedAttributes { get; set; } = default!;
}
I use this technique in this wasm pwa hosted on github pages. It creates a subset of twitters bootstrap icons.
I pass there existing svg using:
using var reader = new StreamReader(content);
XDocument document = XDocument.Load(reader);
XElement svgElement = document.Root!;
foreach (var element in svgElement.Elements().ToList())
{
...
}

Setting #Font-Face From C# Code Behind

In my stylesheet I have this declared
#font-face {
font-family: 'light';
src: url('Fonts/HelveticaNeueLTStd-Lt.otf') format('opentype');
}
Now in my C# code behind I try to set the class like this
row.CssClass = light;
But I get a compile error of
The name 'light' does not exist in the current context
Is it possible to reference a css class #font-face from C# codebehind?
EDIT
This is how I am attempting to use this - I have tried the below
.lightfontface {
font-family: 'light';
}
#font-face {
font-family: 'light';
src: url('Fonts/HelveticaNeueLTStd-Lt.otf') format('opentype');
}
row.CssClass = lightfontface;
I believe your
row.CssClass = light;
needs to be
row.CssClass = "className";
and your css will need a .className entry.
Imagine your html row:
<tr class="className">stuff</tr>
Your CssClass assignment is assigning the value to class, and your css can use a class selector to format that row.
To sum up some of the comments, the style sheet entry should simply be:
.className { font-family: 'light'; }
Ordering on your style sheet is important. Put the font-face definition above the .className style entry. See: https://www.w3.org/TR/CSS2/cascade.html#cascading-order

Multiple ajax requests or one shot?

I encounter some design problems.
I have a page with a JQuery Calendar (full-calendar) and I need to retrieve two IDs depending on the current month.
Which is the best solution ?
Retrieve the IDs using an Ajax Request each time the calendar is re-rendered (the month changed)
Loading all the Ids (I use Asp.Net Mvc) once and then filtering.
I tried to use the first solution but when the user switch the month too fast (January to February per example), it affects January IDs to February because the user switched too fast (before the first requests actually finished).
Hope I'm clear.
Thank you in advance.
The First Method is prefereable. What you can do is add a time disable ,for me a loader is of best usage in this type of situations
Css :
body.loading {
overflow: hidden;
}
body.loading .modal1 {
display: block;
}
.modal1 {
display: none;
position: fixed;
z-index: 1000;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba( 255, 255, 255, .8 )
url('Loaderurl')
50% 50%
no-repeat;
}
View -
add this at bottom
<div class="modal1"></div>
Script-
$body = $("body");
$(document).on({
ajaxStart: function () {
$body.addClass("loading");
},
ajaxStop: function (e) {
$body.removeClass("loading");
}
});
Thanks for the help.
What I chose to do is to initialize an array where I put all the needToCancel ajax requests and created a cancelAjaxRequests method that I call each time I change the month.
var lastMonthAjaxRequests = [];
lastMonthAjaxRequests.push(... my ajax requests...)
function abortAjaxRequests(ajaxRequests) {
$.each(ajaxRequests,
function() {
this.abort();
});
}
Then each time my calendar is re-rendered :
abortAjaxRequests(lastMonthAjaxRequests);
lastMonthAjaxRequests = [];

How can I get text in an HTML tr (table row) to center?

I'm building some HTML in a StringBuilder like so:
builder.Append("<tr align='center' valign='top' class=\"skyBlueBackground textAlignCenter\">");
List<String> columnHeadings = GetColumnHeadings(monthCount, _begindate);
foreach (String s in columnHeadings)
{
if (s.Equals("Grand Total"))
{
builder.Append("<td align='left' valign='top' class=\"forestGreenBackground whiteText\"><b>");
}
else
{
builder.Append("<td align='left' valign='top'><b>");
}
builder.Append(s);
builder.Append("</b></td>");
}
builder.Append("</tr>");
Although I've got a class for centering text:
builder.Append("</style>");
. . .
builder.Append(".textAlignCenter { text-align: center; }");
builder.Append("</style>");
...the text is aligned left; it works other than that (skyblue background), it just stays magnetized to the left:
What must I do to get the text to center?
You should either set the textAlignCenter on the TD, not the TR or change the CSS definition to:
builder.Append(".textAlignCenter td { text-align: center; }");
And you should remove the explicit "align='left'" from your TD because that will still overrule the CSS.
If you are asking for how to vertically align the text, you could use the vertical-align CSS property. See here for more info.
You could also use the valign attribute, but it is deprecated in HTML5 and it is not a recommended approach.
Your problem is simply, you have created correctly the css class property .textAlignCenter, but your attribute align="left" on the <td> has style priority.
I think you can do two solutions:
Put the class .textAlignCenter on the td you want to align
center.
Remove the align="center" of the td and add a css like
this:
tr td {text-align:left}
tr td.textAlignCenter {text-align:center}
With this last solution you overwrite the last style.

Is it possible to run JavaScript within a webBrowser Control without accessing a specific page?

I am building a web page live as output for my application. This means that I'm editing the document text directly, instead of pointing the control to a file. I have the following code:
<html>
<head>
<style type = "text/css">
.circle {
position:relative;
moz-border-radius: 10px;
-webkit-border-radius: 10px;
-khtml-border-radius: 10px;
border-radius: 10px;
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid #000;
height: 10px;
width: 10px;
background-color:#33FF00;
}
</style>
<script type="text/javascript">
var step = 0;
var color= '#0000FF';
function timer()
{
var t=setTimeout("switchColor()",125);
}
function switchColor()
{
if (step == 0) {color='#33FF00';}
if (step == 1) {color='#33FF00';}
if (step == 2) {color='#22AA55';}
if (step == 3) {color='#1155AA';}
if (step == 4) {color='#0000FF';}
if (step == 5) {color='#0000FF';}
if (step == 6) {color='#1155AA';}
if (step == 7) {color='#22AA55';}
step = step+1;
if (step > 7) { step = 0;}
var elements = document.getElementsByClassName('circle')
for (var i = 0;i <elements.length;i++)
{
elements[i].style.backgroundColor=color;
}
timer()
}
</script>
</head>
<body onload="timer()" >
<div id="test" class="circle1"></div>
<div class="circle"></div><div class="circle"></div>
<br>
<br>
</body>
</html>
That code is then set as the documentText of a webBrowser control by using a stringBuilder, adding each line with the StringBuilder.AppendLine() function, and then converting the entire stringBuilder to a string.
I get the error that the getElementsByClassName function is not supported, and nothing happens. The html runs perfectly on its own.
The WebBrowser Control can run javascript live, but it has the same limitations as Internet Explorer. Any commands used within the control need to be able to run in Internet Explorer on the associated machine.
You´ll need to use getElementsByTagName('*'), iterate over the list and verify if each item has the desired className.
As an answer for you, I propose that you use jQuery. It can find elements that have a certain class and works great in IE. Specifically look at the class selector.
www.jquery.com
http://api.jquery.com/class-selector/

Categories

Resources