Saturday, June 7, 2014

Change the CSS class of div made into a web forms control in C#.

<div id="Whatever" runat="server" class="displaynone">
   The quick red fox jumps over the lazy brown dog.
</div>

 
 

What is above may be manipulated like so.

private void Tweak(int foo)
{
   if (foo > 0)
   {
      Whatever.Attributes["class"] = "";
   } else {
      Whatever.Attributes["class"] = "displaynone";
   }
}

 
 

See also my trick for manipulating styles here.

A DevExpress ASPxNavBar is, I think, a bar one may click to make an expandable area expand into view or collapse away from view.

<dx:PanelContent>
   <dx:ASPxNavBar ID="MyNav" runat="server" EnableCallBacks="true" Width="100%"
         ClientInstanceName="MyNav" RenderMode="Lightweight">
      <ClientSideEvents EndCallback="Whatever" />
      <GroupContentTemplate>
         <asp:Panel ID="WorkFlowTemplatePanel" runat="server">
         </asp:Panel>
      </GroupContentTemplate>
   </dx:ASPxNavBar>
</dx:PanelContent>

HtmlDataCellPrepared versus HtmlRowPrepared at DevExpress ASPxGridViews

I had a problem in crafting hyperlinks within a DevExpress ASPxGridView like this in that when I had a JavaScript effect which had to happen upon a mouseover like so:

hyperLink.Attributes.Add("onmouseover", String.Format("ShowToolTips('{0}','{1}',',')", hyperLink.ClientID, _errors));

 
 

...there was a problem! One had to click in the page before the mouseover effect would work! At my wireup like this...

Foo.HtmlDataCellPrepared += Foo_HtmlDataCellPrepared;

 
 

...which used a method such as this...

private void Foo_HtmlDataCellPrepared(object sender, ASPxGridViewTableDataCellEventArgs e)
{

 
 

...I ended up giving up on an expectation of hyperlink management. I instead added a new wireup like this...

Foo.HtmlRowPrepared += Foo_HtmlRowPrepared;

 
 

...which used a method such as this...

private void Foo_HtmlRowPrepared(object sender, ASPxGridViewTableRowEventArgs e)
{

 
 

...which could affect a column like this...

<dx:GridViewDataTextColumn Caption="Validation" Width="80px">
   <DataItemTemplate>
      <asp:HyperLink ID="ValidationLinkButton" runat="server" CausesValidation="false"
            CssClass="FooErrorLink">
      </asp:HyperLink>
   </DataItemTemplate>
</dx:GridViewDataTextColumn>

 
 

...like so:

private void Foo_HtmlRowPrepared(object sender, ASPxGridViewTableRowEventArgs e)
{
   var grid = sender as ASPxGridView;
   if (grid == null) return;
   var hyperLink = grid.FindRowCellTemplateControl(e.VisibleIndex, null,
         "ValidationLinkButton") as HyperLink;
   if (e.RowType == GridViewRowType.Data && hyperLink != null)
   {
      var foo = grid.GetRow(e.VisibleIndex) as Foo;
      if (!string.IsNullOrEmpty(foo.FlattenedErrorList))
      {
         hyperLink.Text = "Error";
         hyperLink.Enabled = false;
         hyperLink.Attributes.Add("onmouseover", String.Format("ShowToolTips('{0}','{1}',',')",
               hyperLink.ClientID, _errors));
      } else {
         hyperLink.Visible = false;
      }
   }
}

 
 

Hmmm... as I type this I'm not sure this had to be done. I also changed a CSS class at the links and that helped big. :P

Monday, June 2, 2014

Spin up two threads in C# and wait for them both to finish before proceeding.

I opened up C# 4.0 in a Nutshell by Joseph and Ben Albahari again today. In stared at pages 833 and 835 and then wrote this:

using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Web.Mvc;
namespace YingYang.Controllers
{
   public class HomeController : Controller
   {
      static EventWaitHandle _waitForYing = new AutoResetEvent(false);
      static EventWaitHandle _waitForYang = new AutoResetEvent(false);
      private const int _yingSleep = 3000;
      private const int _yangSleep = 4000;
      
      public ActionResult Ying()
      {
         new Thread(Yang).Start();
         using (Stream x = new FileStream(@"C:\Apps\YingYang\ying.txt",
               FileMode.Append))
         {
            byte[] foo = ASCIIEncoding.ASCII.GetBytes(DateTime.Now.ToString() + "\r\n");
            x.Write(foo, 0, foo.Length);
            Thread.Sleep(_yingSleep);
            byte[] bar = ASCIIEncoding.ASCII.GetBytes(DateTime.Now.ToString() + "\r\n");
            x.Write(bar, 0, bar.Length);
            Thread.Sleep(_yingSleep);
            byte[] baz = ASCIIEncoding.ASCII.GetBytes(DateTime.Now.ToString() + "\r\n");
            x.Write(baz, 0, baz.Length);
            Thread.Sleep(_yingSleep);
            byte[] qux = ASCIIEncoding.ASCII.GetBytes(DateTime.Now.ToString() + "\r\n");
            x.Write(qux, 0, qux.Length);
            Thread.Sleep(_yingSleep);
         }
         _waitForYing.Set();
         _waitForYang.WaitOne();
         return View(DateTime.Now);
      }
      
      static void Yang()
      {
         using (Stream x = new FileStream(@"C:\Apps\YingYang\yang.txt",
               FileMode.Append))
         {
            byte[] foo = ASCIIEncoding.ASCII.GetBytes(DateTime.Now.ToString() + "\r\n");
            x.Write(foo, 0, foo.Length);
            Thread.Sleep(_yangSleep);
            byte[] bar = ASCIIEncoding.ASCII.GetBytes(DateTime.Now.ToString() + "\r\n");
            x.Write(bar, 0, bar.Length);
            Thread.Sleep(_yangSleep);
            byte[] baz = ASCIIEncoding.ASCII.GetBytes(DateTime.Now.ToString() + "\r\n");
            x.Write(baz, 0, baz.Length);
            Thread.Sleep(_yangSleep);
            byte[] qux = ASCIIEncoding.ASCII.GetBytes(DateTime.Now.ToString() + "\r\n");
            x.Write(qux, 0, qux.Length);
            Thread.Sleep(_yangSleep);
         }
         _waitForYing.WaitOne();
         _waitForYang.Set();
      }
   }
}

 
 

ying.txt ended up with this in it when I ran the app I made:

6/2/2014 6:01:00 PM
6/2/2014 6:01:03 PM
6/2/2014 6:01:06 PM
6/2/2014 6:01:09 PM

 
 

yang.txt ended up with this in it when I ran the app I made:

6/2/2014 6:01:00 PM
6/2/2014 6:01:04 PM
6/2/2014 6:01:08 PM
6/2/2014 6:01:12 PM

 
 

The DateTime value which makes it into the view ends up being coughed up as a string to the user and it looks like this:

6/2/2014 6:01:16 PM

 
 

If _yangSleep is set to 2000 instead, the application doesn't behave appreciably different. Both text files will still end up with dates in them which come before the date that ends up making its way into the UI's HTML. Both threads finish their file I/O mechanics before this line of code is ever run:

return View(DateTime.Now);

 
 

This outcome will happen without regard to which thread is speedier in getting its work done.