If using ASP.NET EntityDataSource and databound controls you may need to access the actual entity object being represented in the control, e.g. a data row in a table or a single entity in a FormView. The actual entity is not readily available however as it is automatically wrapped in a System.Web.UI.WebControls.EntityDataSourceWrapper which is not accessible. The extension method below allows you to gain access to the strongly typed, underlying entity. It is based on the article by Diego Vega which explains the wrapping behaviour in more detail.
/// <summary>
/// Gets the actual EF entity object that is being wrapped and databound.
/// </summary>
/// <example>
/// Advert ad = myFormView.DataItem.WrappedEntity<Advert>();
/// (where myFormView is databound to EntityDataSource returning Advert entity)
/// </example>
static class WrappedEFEntityExtensions
{
public static TEntity WrappedEntity<TEntity>(this object dataItem) where TEntity : class
{
var entity = dataItem as TEntity;
if (entity != null)
return entity;
var typeDescriptor = dataItem as ICustomTypeDescriptor;
if (typeDescriptor != null)
return (TEntity)typeDescriptor.GetPropertyOwner(null);
return null;
}
}
SHARE:
Rather than taking an array of Color objects, the WritableBitmap.Pixels property holds an array on ints which represent premultiplied ARGB colour values. To set a given pixel to a given colour you have to take the alpha, red, green and blue values and convert them to a premultiplied ARGB int value.
The following code contains some helpers/extension methods to make the process bit easier, for example to set every pixel to red:
for (int index = 0; index < bmp.Pixels.Length; index++)
{
Color myColour = new Color() { A = 255, R = 255, G = 0, B = 0 };
bmp.Pixels[index] = myColour.ToWritableBitmapPixelValue();
}
or using the Fill extension method:
bmp.Fill( new Color() { A = 255, R = 255, G = 0, B = 0 } );
WritableBitmapHelper class listing
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
namespace BitmapAPI
{
/// <summary>
/// Helper methods\extension methods for dealing with WritableBitmap,
/// in real world implementation you'd probably choose to separate the
/// extension methods iinto separate static classes;
/// eg WritableBitmapExtensions & ColorExtensions
/// </summary>
public static class WritableBitmapHelper
{
/// <summary>
/// Converts ARGB byte values to an integer
/// Based on info found at:
/// http://blogs.silverarcade.com/silverlight-games-101/15/silverlight-writeablebitmap-pixel-format-in-silverlight-3/
/// </summary>
/// <param name="alpha">Alpha transparency: 0=transparent 255=solid</param>
/// <param name="red">Amount of red: 0 to 255</param>
/// <param name="green">Amount of green: 0 to 255</param>
/// <param name="blue">Amount of blue: 0 to 255</param>
/// <returns>An integer representing an ARGB color</returns>
public static int CalcWritableBitmapPixelValue(byte alpha, byte red, byte green, byte blue)
{
// Calc premultiplier once only. We need to use premultiplied ARGB32
// rather than convential ARGB.
double alphaPreMultiplier = alpha / 255d;
// Premultiply rgb values with alpha
byte r = (byte)(red * alphaPreMultiplier);
byte g = (byte)(green * alphaPreMultiplier);
byte b = (byte)(blue * alphaPreMultiplier);
return (alpha << 24) | (r << 16) | (g << 8) | b;
}
/// <summary>
/// Extension method to convert a System.Windows.Media.Color to an integer value.
/// </summary>
/// <param name="color">The System.Windows.Media.Color to convert</param>
/// <returns>An integer representing the ARGB values of <paramref name="color"/></returns>
public static int ToWritableBitmapPixelValue(this Color color)
{
return CalcWritableBitmapPixelValue(color.A, color.R, color.G, color.B);
}
/// <summary>
/// Extension method to 'fill' a WriteableBitmap with a given solid color
/// </summary>
/// <param name="bmp">The WriteableBitmap to fill</param>
/// <param name="color">The Color to fill with</param>
public static void Fill(this WriteableBitmap bmp, Color color)
{
for (int i = 0; i < bmp.Pixels.Length; i++)
{
bmp.Pixels[i] = color.ToWritableBitmapPixelValue();
}
}
}
}
SHARE:
Extension methods allow you to extend the functionality of an existing class without using inheritance.
For example, suppose you were implementing a system which allowed users to post comments on a web site but you wanted to disallow swear words or other offensive content.
You could write a SwearChecker class (static or otherwise) or you could enable the same functionality by adding an extension method to the String class.
An extension method is defined a static method within a static class. The keyword this
is used before the first method parameter and signifies the type that is being extended.
The following defines an extension method for String.
public static class OffensiveStringExtensions
{
public static bool IsOffensive(this string stringToCheck)
{
// define list of offensive words (real swear words omitted...)
List<string> offensiveWords = new List<string> {"darn", "damn", "blast"};
foreach (var offesiveWord in offensiveWords)
{
// A real implementation may need to handle uppercase, localisation, etc.
if (stringToCheck.Contains(offesiveWord))
return true;
}
// no offensive words found
return false;
}
}
The extension method is called just as if it were a member of the type itself:
string wordsToCheck = "This is darn offensive!";
if (wordsToCheck.IsOffensive())
//.... perform some logic ....
MSDN states: "In general, we recommend that you implement extension methods sparingly and only when you have to. Whenever possible, client code that must extend an existing type should do so by creating a new type derived from the existing type."
We cannot inherit from String because it is sealed, so an extension method is one way of adding this functionality to all strings.
Some things to note when using extension methods:
- If an extension method has the same signature as an instance method, the instance method will be used and the extension method will never be called;
- The extension method can't access private members of the type it is extending;
If you want to fill in the gaps in your C# knowledge be sure to check out my C# Tips and Traps training course from Pluralsight – get started with a free trial.
SHARE: