WPF 4 DataGrid: Getting the Row Number into the RowHeader

After struggling way too long on this, I posted the question to StackOverflow and of course, received a fairly quick answer (thanks Meleak!).  Since I couldn’t find any good solutions out there with Google & Bing, I thought I’d post it here for the next person struggling with this.

What I was trying to do was get the row number into the RowHeader of the DataGrid, so it has an Excel-ish column to let my users see which record in the set they were looking at.  The solution I’ve seen out there on the web suggests adding an index field to the business objects. This wasn’t really an option for me at this point because the DataGrid will be getting resorted a lot and we don’t want to have to keep track of changing these index fields constantly just to show row numbers on the grid.

The solution required a smidgen of code-behind which some developers frown upon, but this is solely for the way the grid looks so I was much more comfortable keeping this with the UI logic as opposed to throwing extraneous fields on my business objects to help with how the UI looks.

  1. <!– DataGrid XAML –>
  2. <DataGrid LoadingRow="DataGrid_LoadingRow"
  3.  
  4.     ———————
  5.  
  6. // Code Behind
  7. private void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
  8. {
  9.     e.Row.Header = (e.Row.GetIndex() + 1).ToString();
  10. }

 

The result, a DataGrid with a row header for my rows that specifies the row number…that doesn’t get changed as my grid is sorted and resorted and resorted.

DataGridRowHeaders

Posted in WPF | Tagged | 12 Comments

WPF Date Range Double Slider Control (Part 1)

As I mentioned in my introduction to this series, I’m going over various aspects of how I created a DateTime Range slider control.  In this article, I’m going to be going over the basics of creating the user control.  Source for this project can be found on CodePlex.

First, to get two thumbs onto the slider, I overrode the control template of the regular slider with a template called “simpleSlider” to get rid of the track of each slider as well as some other default pieces of the base control template such as the repeater buttons.  With these things there, one or the other of the sliders would sit on top of the other and really just mess with my users’ experience.

Slider Control Template
  1. <ControlTemplate x:Key=“simpleSlider” TargetType=”{x:Type Slider}>
  2.     <Border SnapsToDevicePixels=“true” BorderBrush=”{TemplateBinding BorderBrush} BorderThickness=”{TemplateBinding BorderThickness}>
  3.         <Grid>
  4.             <Grid.RowDefinitions>
  5.                 <RowDefinition Height=“Auto”/>
  6.                 <RowDefinition Height=“Auto” MinHeight=”{TemplateBinding MinHeight}/>
  7.                 <RowDefinition Height=“Auto”/>
  8.             </Grid.RowDefinitions>
  9.  
  10.             <Rectangle x:Name=“PART_SelectionRange”/>
  11.  
  12.             <Track x:Name=“PART_Track” Grid.Row=“1”>
  13.                 <Track.Thumb>
  14.                     <Thumb x:Name=“Thumb” Style=”{StaticResource ResourceKey=HorizontalSliderThumbStyle} />
  15.                 </Track.Thumb>
  16.             </Track>
  17.         </Grid>
  18.     </Border>
  19. </ControlTemplate>

 

Then my control is made with the two sliders that use the “simpleSlider” template and a single Border control to be my track for the two sliders:

DateTime Range Slider
  1. <Grid VerticalAlignment=“Center” Background=“Transparent”>
  2.     <Border BorderThickness=“0,1,0,0” BorderBrush=“DarkGray” VerticalAlignment=“Bottom” Height=“1” HorizontalAlignment=“Stretch”
  3.            Margin=“0,0,0,10”/>
  4.  
  5.     <Slider x:Name=“LowerSlider” VerticalAlignment=“Top” IsEnabled=”{Binding ElementName=root, Path=IsLowerSliderEnabled, Mode=TwoWay}
  6.            Minimum=”{Binding ElementName=root, Path=Minimum, Converter={StaticResource ResourceKey=dtdConverter}}
  7.            Maximum=”{Binding ElementName=root, Path=Maximum, Converter={StaticResource ResourceKey=dtdConverter}}
  8.            Value=”{Binding ElementName=root, Path=LowerValue, Mode=OneWay, Converter={StaticResource ResourceKey=dtdConverter}}
  9.            Template=”{StaticResource simpleSlider}
  10.            Margin=“0,0,10,0”
  11.            SmallChange=”{Binding ElementName=root, Path=SmallChange, Converter={StaticResource ResourceKey=timespanToDoubleConverter}}
  12.            LargeChange=”{Binding ElementName=root, Path=LargeChange, Converter={StaticResource ResourceKey=timespanToDoubleConverter}}
  13.             />
  14.  
  15.     <Slider x:Name=“UpperSlider” IsEnabled=”{Binding ElementName=root, Path=IsUpperSliderEnabled, Mode=TwoWay}
  16.            Minimum=”{Binding ElementName=root, Path=Minimum, Converter={StaticResource ResourceKey=dtdConverter}}
  17.            Maximum=”{Binding ElementName=root, Path=Maximum, Converter={StaticResource ResourceKey=dtdConverter}}
  18.            Value=”{Binding ElementName=root, Path=UpperValue, Mode=OneWay, Converter={StaticResource ResourceKey=dtdConverter}}
  19.            Template=”{StaticResource simpleSlider}
  20.            Margin=“10,0,0,0”
  21.            SmallChange=”{Binding ElementName=root, Path=SmallChange, Converter={StaticResource ResourceKey=timespanToDoubleConverter}}
  22.            LargeChange=”{Binding ElementName=root, Path=LargeChange, Converter={StaticResource ResourceKey=timespanToDoubleConverter}}
  23.             />
  24. </Grid>

 

Mainly because I didn’t want to spend the time (at this point) dealing with making this a slider that could handle more than just a DateTime range, the Minimum, Maximum, and Value properties of the sliders are using an IValueConverter to handle the conversion between the doubles the sliders expose to DateTime values.  The SmallChange and LargeChange properties are converted from TimeSpans my control expects to doubles that the slider controls expect.

DateTime to Double Converter
  1. public class DateTimeDoubleConverter : IValueConverter
  2. {
  3.     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  4.     {
  5.         DateTime dt = DateTime.Parse(value.ToString());
  6.         return dt.Ticks;
  7.     }
  8.  
  9.     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  10.     {
  11.         double d = double.Parse(value.ToString());
  12.         return new DateTime((long)d);
  13.     }
  14. }
TimeSpan to Double Converter
  1. public class TimeSpanToDoubleConverter : IValueConverter
  2. {
  3.     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  4.     {
  5.         TimeSpan givenValue = (TimeSpan)value;
  6.         return givenValue.Ticks;
  7.     }
  8.  
  9.     public object ConvertBack(object value, Type targetType,
  10.        object parameter, System.Globalization.CultureInfo culture)
  11.     {
  12.         return new TimeSpan(((long)value));
  13.     }
  14. }

Posted in C#, WPF | Tagged , , , | Leave a comment

WPF Date Range Double Slider Control (Introduction)

For a project I’m working on, I needed a way to select a date range.  One of my first thoughts was to use a double slider only to find that one didn’t exist with the OOTB controls so I decided to roll my own.   In order to solidify things in my mind as well as help anyone out there looking for resources on various aspects of development in WPF, I thought I’d write about my experience creating this control.

I’ll be adding blog entries in the next week or two to describe how I accomplished implemenation of some of the features I wanted in my control:

  • Create a two-thumbed slider control to choose a DateTime range. (Part 1)
  • Don’t let the the lower slider or upper slider pass each other.  I was creating this to use with a graph and if the sliders passed each other even for a millisecond, the graph would throw an exception. (Part 2)
  • Dependency Properties  (Part 3)

I did lose some of the functionality of the regular slider in my first version of this control, such as clicking to the right or left of the thumb to change the value and displaying the slider in a vertical format, but overall, I’m happy with this control as it is so far (and so was my client.)

Because I wanted to continue work on this control and make it easy to download and use the code, the source for the control and a sample project are available at CodePlex.

Posted in C#, WPF | Tagged , | 11 Comments

Image Source Converter

Each time I have the need for an image converter for a WPF application, I end up searching the web looking for a sample, so this time, I’m putting a sample somewhere I can find it again easily.  Below is a basic IValueConverter implementation to convert a file name into a BitmapImage located in an images folder.

Code for Sample Project

public class IconImageConverter : IValueConverter
{
    public object Convert(object value, 
                       Type targetType, 
                       object parameter, 
                       System.Globalization.CultureInfo culture)
   {
      // if value isn't null, we can safely do the conversion. 
      if (value != null)
      {
          string imageName = value.ToString();
          Uri uri = new Uri(String.Format("/Images/{0}", imageName), 
                                UriKind.Relative);
          return new BitmapImage(uri);
      }
      return null;
   }
    public object ConvertBack(object value, 
                         Type targetType, 
                         object parameter, 
                         System.Globalization.CultureInfo culture)
    {
       throw new NotImplementedException();
    }
}
Aside | Posted on by | Tagged , | 1 Comment

Hide Ribbon Bar from Anonymous Users

A quick and simple way to hide the ribbon bar from anonymous users is to add the snippet of code to your Master Page or Page Layout.  When I first discovered this, my response was…”oh….DUH!!”

<asp:LoginView ID="LoginView1" runat="server">
    <AnonymousTemplate>
        <style type="text/css">
            #s4-ribbonrow { display: none; }
        </style>
    </AnonymousTemplate>
</asp:LoginView>

The idea is simple.  Use the ASP.NET LoginView control to add a conditional CSS block that hides the entire blue ribbon row.

Posted in SharePoint 2010 | Leave a comment

SQL Management Studio 2008 – Query Editor Tabs

I am constantly working with multiple databases on different servers in SQL Management Studio 2008.  I am rarely working with saved files and usually with my own account, but by default, each tab just shows me the generic file names and my account.  In order easily find the correct tab I want to work with, I’ve modified the display of the editor tabs within the options to only show me the server name and the database name the query is working with.

Open Dialog:  Tools –> Options…

Location:  Text Editor –> Editor Tab and Status Bar –> Tab Text

 

This gives me query editor tabs with just the Server and Database names so I can find my way to the queries I’m looking for easier.

Posted in Tips & Tricks | Leave a comment

Building a WCF client without config file

I recently had to make a service call to a WCF service from within a K2 blackpearl code event and didn’t have access to the configuration file to configure my binding and endpoint.  I created the client using the Svcutil.exe tool and then built a basic WSHttpBinding and EndpointAddress to call the constructor of my client so I could get to work and use it.

   1: //Build a basic WSHttpBinding object
   2: var myBinding = new System.ServiceModel.WSHttpBinding();
   3:  
   4: // Build the Services EndPoint.
   5: var myEndpointAddress = new System.ServiceModel.EndpointAddress(webserver + "/Services/MyWCFService.svc");
   6:  
   7: // Create a WCF Service Client instance.
   8: MyWCFServiceClient client = new MyWCFServiceClient(myBinding, myEndpointAddress);
   9:  

This worked for a little bit, however, it turned out my EndpointAddress was a little too simple when the application pool was changed by our administrator to run under a domain account’s credentials and I started receiving the error below.

System.ComponentModel.Win32Exception (0x80004005): Security Support Provider Interface (SSPI) authentication failed. The server may not be running in an account with identity ‘host/servername. If the server is running in a service account (Network Service for example), specify the account’s ServicePrincipalName as the identity in the EndpointAddress for the server. If the server is running in a user account, specify the account’s UserPrincipalName as the identity in the EndpointAddress for the server.

To fix the problem, I had to tweak how I created my so that I passed in a DNS identity of the local system.  The code below is the code that got things working again.

   1: //Build a basic WSHttpBinding object
   2: var myBinding = new System.ServiceModel.WSHttpBinding();
   3:  
   4: // Build the Services EndPoint.
   5: var myEndpointAdd = new EndpointAddress(new Uri(webserver + "/Services/MyWCFService.svc"),
   6:      EndpointIdentity.CreateDnsIdentity("localhost"));
   7:  
   8: // Create a WCF Service Client instance.
   9: MyWCFServiceClient client = new MyWCFServiceClient (myBinding, myEndpointAdd);
Posted in WCF | 1 Comment

Telerik ASP.NET AJAX – Giving focus to a DatePicker after AJAX callback.

I had a form with three Telerik DatePickers controls and had enabled postback on the first two to perform some server-side work.  The sample code attached is just setting the minimum date for the other DatePickers on the form.  After returning from postback, I expected the next DatePicker to have focus, but I could not get it to happen.  I sent the Telerik support team a message asking for help and the solution came quick and was very simple:

    protected void RadDatePicker1_SelectedDateChanged(object sender, Telerik.Web.UI.Calendar.SelectedDateChangedEventArgs e)
    {
        if (e.NewDate.HasValue)
        {
            RadDatePicker2.MinDate = e.NewDate.Value;
            RadDatePicker3.MinDate = e.NewDate.Value;
            RadAjaxManager1.FocusControl(RadDatePicker2.DateInput.ClientID + "_text");
        }
    }

    protected void RadDatePicker2_SelectedDateChanged(object sender, Telerik.Web.UI.Calendar.SelectedDateChangedEventArgs e)
    {
        if (e.NewDate.HasValue)
        {
            RadDatePicker3.MinDate = e.NewDate.Value;
            RadAjaxManager1.FocusControl(RadDatePicker3.DateInput.ClientID + "_text");
        }
    }
Posted in Telerik ASP.NET AJAX | Leave a comment

Talking about Studio Styles – Visual Studio color schemes

A site like Studio Styles has been needed for a long time and I’m very grateful for Luke Sampson who is the one who finally put it together and launched it in his spare time.  I always have to do a lot of searching to find schemes that I want to start with and now I can find them all in one place.  Thank you Luke!
 
Posted in Visual Studio | Leave a comment

Using jQuery and a Select box to show content

 

I saw a question in a forum asking how to show content based on which value was displayed chosen in a select box.  I threw together this small sample to illustrate one way you could do this using jQuery.

The full HTML file is attached.

Code Snippet
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  2.  
  3. <html xmlns="http://www.w3.org/1999/xhtml"&gt;
  4. <head>
  5.     <title></title>
  6.         <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js&quot; type="text/javascript"></script>
  7.         <script type="text/javascript">
  8.             $(document).ready(function() {
  9.             });
  10.  
  11.             // Event Handler for the OnChange event of the Select1
  12.             function SelectedItemChanged() {
  13.                 // Gets the value of Select1
  14.                 var x = $("select#Select1").val();
  15.                 // Ensures that the corresponding paragraph is visible
  16.                 ShowItem(x);
  17.  
  18.                 // Loops through all of the options for Select1 and hides them if they aren’t the selected option
  19.                 $("select#Select1 option").each(function(i) {
  20.                     if ($(this).val() != x) {
  21.                         HideItem($(this).val());
  22.                     }
  23.                 });
  24.         }
  25.  
  26.         function ShowItem(alpha) {
  27.             $("#changingArea #" + alpha).show();
  28.         }
  29.  
  30.         function HideItem(alpha) {
  31.             $("#changingArea #" + alpha).hide();
  32.         }
  33.         </script>
  34. </head>
  35. <body>
  36.     <select id="Select1" name="Select1" onchange="javascript:SelectedItemChanged();">
  37.         <option>A</option>
  38.         <option>B</option>
  39.         <option>C</option>
  40.         <option>D</option>
  41.         <option>E</option>
  42.     </select>
  43.     
  44.     <div id="changingArea">
  45.         <div id="A">Paragraph 1</div>
  46.         <div id="B">Paragraph 2</div>
  47.         <div id="C">Paragraph 3</div>
  48.         <div id="D">Paragraph 4</div>
  49.         <div id="E">Paragraph 5</div>
  50.     </div>
  51. </body>
  52. </html>

Posted in jquery | Leave a comment