Subscribe: Naughton Futilities
http://weblogs.asp.net/naughton/rss.aspx
Added By: Feedage Forager Feedage Grade B rated
Language: English
Tags:
color rgb  color  control  dataform  margin  net  new  null  public  silverlight  size small  size  small  top  typeof  xsd 
Rate this Feed
Rate this feedRate this feedRate this feedRate this feedRate this feed
Rate this feed 1 starRate this feed 2 starRate this feed 3 starRate this feed 4 starRate this feed 5 star

Comments (0)

Feed Details and Statistics Feed Statistics
Preview: Naughton Futilities

Naughton Futilities



No Relation



 



Blog migrated to Orchard

Sat, 24 May 2014 10:41:00 GMT

Looks like the admins have made Orchard the blog engine here.

I can also use Markdown to edit blog posts.




MvcScaffolding Enhancement - DisplayAttribute Support

Sat, 21 May 2011 17:07:00 GMT

Steve Sanderson has an excellent blog series, describing his MvcScaffolding NuGet Package.

For example, I was reading his post, describing how to override the T4 Template output generated by MvcScaffolding:

http://blog.stevensanderson.com/2011/04/06/mvcscaffolding-overriding-the-t4-templates/

I wanted to add support for any DisplayAttribute DataAnnotations on my Model classes, in those parts of the Razor views not handled by HtmlHelpers.

For example, labels for dropdown lists for RelatedEntities were based on the RelatedEntity Name property value.

With a small additional amount of logic, any associated DisplayAttribute Name can be obtained and used as an override.

The attached ZIP file contains the results of my experiments.

To use in an existing MVC3 application, simply unzip the contents of the attachment and include the CodeTemplates folder in the MVC3 Project, as a child of the root folder. Using this well-known location, MvcScaffolding will use these replacement templates instead of the defaults.




Silverlight Business Application - Side Navigation Bar

Tue, 15 Jun 2010 18:28:00 GMT

If you're using the Silverlight Business Application template, you may have also noticed the recently-released Silverlight 4 Theme Refresh:

http://www.microsoft.com/downloads/details.aspx?FamilyID=e9da0eb8-f31b-4490-85b8-92c2f807df9e&displaylang=en

As an experiment, I wanted to move the Navigation links to the left-hand-side of the display, to allow more flexibility to add links at a later stage. (I also added a GridSplitter)

I've attached the Win7 Solution template, as a proof-of-concept.




Silverlight Business Application Themes - ErrorWindow Issues

Tue, 15 Jun 2010 16:46:00 GMT

If you're using the Silverlight Business Application template, you may have noticed some issues, particularly if you have tried the recently-released Silverlight 4 Theme Refresh: http://www.microsoft.com/downloads/details.aspx?FamilyID=e9da0eb8-f31b-4490-85b8-92c2f807df9e&displaylang=en The text in the OK button is cropped in the new Themes. This is because the Button is defined with fixed Height and Width. Changing these attributes to MinHeight and MinWidth deals with that problem.



Silverlight 3 DataForm ValueConverter - Add Extensibility

Sat, 01 Aug 2009 16:45:00 GMT

A recent post described how to obtain extensibility, with respect to DataForm Control Mapping: http://weblogs.asp.net/naughton/archive/2009/08/01/silverlight-3-dataform-control-mapping-add-extensibility.aspx It is also convenient to make the DataFormValueConverter feature extensible. The DataFormValueConverter class is used by the DataField as the default binding.Converter setting. If we want to have more control over the IValueConverter implementation that gets used by default, we can add a property to DataForm: public IValueConverter DataFormValueConverter { get; set; } Then, we need to adjust the DataField.UpdateBindingsOnElement method: Old:if (binding.Converter == null) {binding.Converter = new DataFormValueConverter(); } New:if (binding.Converter == null) { //binding.Converter = new DataFormValueConverter();IValueConverter dataFormValueConverter = null; DataForm parentDataForm = this.GetParentDataForm();if (null != parentDataForm) { dataFormValueConverter = parentDataForm.DataFormValueConverter;if (null == dataFormValueConverter) {dataFormValueConverter = new DataFormValueConverter(); } } else {dataFormValueConverter = new DataFormValueConverter(); } binding.Converter = dataFormValueConverter; } Now, in a derived DataForm, I can supply my preferred IValueConverter. For example, I want my IValueConverter to map an empty TextBox.Text to null on the underlying string property: The difference between DataFormValueConverter and my class (DataFormExtendedValueConverter) is in bold below:public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {if (targetType != null && (IsNullableType(targetType) || targetType == typeof(string))) {String strValue = value as String;if (strValue != null && strValue.Length == 0) {return null; } }return value; }   [...]



Silverlight 3 DataForm Control Mapping - Add Extensibility

Sat, 01 Aug 2009 15:51:00 GMT

An earlier posting explains how to perform basic modifications to the Silverlight 3 DataForm control. http://weblogs.asp.net/naughton/archive/2009/08/01/silverlight-3-dataform-control-mapping-basic-modifications.aspx It's convenient if such features are available for extensibility. This can be achieved in a straightforward fashion too. (A modified DataForm project is attached.)The DataForm implements the GenerateField method, which calls the two methods that affect Control mapping.Control control = GetControlFromType(propertyType); DependencyProperty dependencyProperty = GetBindingPropertyFromType(propertyType); We can refactor this area, by introducing a Control Mapping interface (IControlMapper) and a default implementation (ControlMapper). Note: I wanted access to the Custom Attributes on each Property, since Custom Attributes may contain information that influences the Control Mapping process. As such, I tweaked the GenerateField method signature to accept the PropertyInfo for the current Property. We add a property to DataForm: public IControlMapper ControlMapper { get; set; } The GenerateField calling code then changes to the following: private bool GenerateField(PropertyInfo propertyInfo, Type propertyType, string propertyName, BindingMode bindingMode, Panel panel) ...IControlMapper controlMapper = this.ControlMapper;if (null == controlMapper) { controlMapper = new ControlMapper(); } controlMapper.PropertyInfo = propertyInfo; controlMapper.PropertyType = propertyType;Control control = controlMapper.GetControl(); DependencyProperty dependencyProperty = controlMapper.GetBindingProperty(); ... We can now define a derived DataForm class that supplies a different implementation of IControlMapper that performs the required mapping. public interface IControlMapper {PropertyInfo PropertyInfo { get; set; } Type PropertyType { get; set; }Control GetControl(); DependencyProperty GetBindingProperty(); } Here is the refactored ControlMapper base class: public class ControlMapper : IControlMapper {#region IControlMapper Members protected PropertyInfo propertyInfo;public PropertyInfo PropertyInfo { get {return this.propertyInfo; } set {this.propertyInfo = value; } }protected Type propertyType;public Type PropertyType { get {return this.propertyType; } set {this.propertyType = value; } }public virtual Control GetControl() {Type type = this.PropertyType; Debug.Assert(type != null, "The type must not be null.");if (type == typeof(bool)) {return new CheckBox(); }else if (type == typeof(bool?)) {CheckBox checkBox = new CheckBox(); checkBox.IsThreeState = true;return checkBox; }else if (type == typeof(DateTime) || type == typeof(DateTime?)) {return new DatePicker(); }else if (type.IsEnum) {ComboBox comboBox = new ComboBox(); FieldInfo[] valueFieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Static);List valueList = new List();foreach (FieldInfo valueFieldInfo in valueFieldInfos) { Enum value = valueFieldInfo.GetValue(null) as Enum;if (value != null) { valueList.Add(value.ToString()); } } comboBox.ItemsSource = valueList;return comboBox; } else {return new TextBox(); } }public virtual DependencyProperty GetBindingProperty() {Type type = this.PropertyType; Debug.Assert(type != null, "The type must not be null.");if (type == typeof(bool) || type == typeof(bool?)) {return CheckBox.IsCheckedProperty; }else if (type == typeof(DateTime) || type == typeof(DateTime?)) {return DatePicker.SelectedDateProperty; }else if (type.IsEnum) {return ComboBox.SelectedItemProperty; } else {return TextBox.TextProperty; } } #endregion }   [...]



Silverlight 3 DataForm Control Mapping - Basic Modifications

Sat, 01 Aug 2009 13:54:00 GMT

The new DataForm control in the Silverlight Toolkit July 2009 Release does a very nice job of presenting an object in a Form view. If you want to take more control of the default way in which the object's properties are mapped to controls, you can open up the DataForm source code and alter the behaviour. By default, the source code is zipped up at this location upon installation: C:\Program Files\Microsoft SDKs\Silverlight\v3.0\Toolkit\Jul09\Source\Source code.zip The DataForm project can be viewed by loading the RiaClient.Toolkit.sln solution file. The methods to modify are these (in System.Windows.Controls.Data.DataForm.Toolkit/DataForm/DataForm.cs): GetControlFromType GetBindingPropertyFromType If you modify the GetControlFromType method, you may need to alter GetBindingPropertyFromType to synchronise the processing. Their original definition is as follows:private static Control GetControlFromType(Type type) {Debug.Assert(type != null, "The type must not be null.");if (type == typeof(bool)) {return new CheckBox(); }else if (type == typeof(bool?)) { CheckBox checkBox = new CheckBox();checkBox.IsThreeState = true;return checkBox; }else if (type == typeof(DateTime) || type == typeof(DateTime?)) {return new DatePicker(); }else if (type.IsEnum) { ComboBox comboBox = new ComboBox();FieldInfo[] valueFieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Static); List valueList = new List();foreach (FieldInfo valueFieldInfo in valueFieldInfos) {Enum value = valueFieldInfo.GetValue(null) as Enum;if (value != null) { valueList.Add(value.ToString()); } } comboBox.ItemsSource = valueList;return comboBox; } else {return new TextBox(); } }  private static DependencyProperty GetBindingPropertyFromType(Type type) {Debug.Assert(type != null, "The type must not be null.");if (type == typeof(bool) || type == typeof(bool?)) {return CheckBox.IsCheckedProperty; }else if (type == typeof(DateTime) || type == typeof(DateTime?)) {return DatePicker.SelectedDateProperty; }else if (type.IsEnum) {return ComboBox.SelectedItemProperty; } else {return TextBox.TextProperty; } } [...]



Roundtripping SoapDuration and TimeSpan

Wed, 15 Dec 2004 13:52:00 GMT

Clemens Vasters writes about XSD duration and its relationship with the .NET Timespan Type.

Another quirk I have found with usage of these types is the fact that the conversion to the SoapDuration Type was not what I originally expected. It turns out that a Timespan that features a period of "about a year" highlights the issue.

In fact, the conversion to SoapDuration assumes a year to contain 360 days (a month is considered to be 30 days). Therefore, a Timespan of 365 days yields a SoapDuration of "P1Y0M5D", suggesting 365 days = 1 year and 5 days.

The algorithm is based on the standard ISO 8601.




Detect Installed Version of WSE

Thu, 09 Dec 2004 11:52:00 GMT

I asked this question a few months ago but there have been two service packs
since then.

Can anyone recommend a reliable mechanism for the detection of WSE1/WSE2
being installed on a PC?

For example, are there certain installed files and/or registry settings that
exclusively indicate WSE2?

Currently, I check the GAC for file versions. However, I'm not sure how to distinguish Service Packs (I don't/can't have multiple Service Packs installed).

I intend to implement the check in VBScript.

Further, how can we distinguish between an installation of:

WSE1 (RTM)
WSE1 (SP1)

WSE2 (TP)
WSE2 (RTM)
WSE2 (SP1)
WSE2 (SP2)




Access the XmlSerializer Temporary Assembly

Wed, 08 Dec 2004 12:26:00 GMT

I've been using the excellent XmlPreCompiler - GUI by Mathew Nolton, original idea by Chris Sells. My own idea was to extend the GUI to allow me to verify Types in a batch. For example, I sometimes want to check every Type in an Assembly. I have a basic implementation of that idea now. However, the side-effect of this feature is that, if run against an Assembly with hundreds of Types, I end up with literally thousands of files dumped in the "Documents and Settings" area on the hard disk; each XmlSerializer instance generates several temporary files. I then wondered whether I could clean-up these files after a check had been run. Several files are created, all with the same unique file name prefix. However, the XmlSerializer does not expose the details of the temporary Assembly it creates. It turns out, though, that use of Reflection can get the desired result. Here is a simple Helper class, that will return the temporary Assembly from an XmlSerializer instance. Incidentally, my initial experience suggests that the temporary Assembly cannot be deleted in the same session of the XmlPreCompiler - I see AccessViolationExceptions. Perhaps the cleanup must occur in the next session, after the files have been released by the application? using System; using System.Reflection; using System.Xml.Serialization; namespace XmlPreCompiler { /// /// Summary description for XmlSerializerAssemblyHelper. /// public class XmlSerializerAssemblyHelper { public XmlSerializerAssemblyHelper() { // // TODO: Add constructor logic here // } public static Assembly GetTemporaryAssemblyFromXmlSerializer(XmlSerializer xmlSerializer) { if (null == xmlSerializer) { throw new ArgumentNullException("xmlSerializer"); } Assembly xmlSerializerTemporaryAssembly = null; // Use Reflection to access private fields Type xmlSerializerType = xmlSerializer.GetType(); // tempAssembly is the NonPublic Instance Field required // tempAssembly has a NonPublic Type = TempAssembly // Therefore, assign the result to the catch-all object Type object xmlSerializerTemporaryAssemblyUntyped = xmlSerializerType.InvokeMember( "tempAssembly" , BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField , null , xmlSerializer , null ); // Debug // Console.WriteLine("xmlSerializerTemporaryAssemblyUntyped.GetType.Name = {0}", xmlSerializerTemporaryAssemblyUntyped.GetType().Name); // Use Reflection to access private fields // assembly is the NonPublic Instance Field required xmlSerializerTemporaryAssembly = (Assembly)xmlSerializerTemporaryAssemblyUntyped.GetType().InvokeMember( "assembly" , BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField , null , xmlSerializerTemporaryAssemblyUntyped , null ); // Debug // Console.WriteLine("xmlSerializerAssembly.Location = {0}", xmlSerializerTemporaryAssembly.Location); return xmlSerializerTemporaryAssembly; } } }   [...]



xsd:group Gets Lost In Translation

Sun, 05 Dec 2004 16:01:00 GMT

If an XML Schema contains an definition, the contents of the are embedded in the containing . Reasonably, enough, the XSD.EXE tool mimics this behaviour, when generating a .NET class definition - children become fields in the containing class.

However, the fact that these fields originated in a reusable group is lost in the generated code. The developer working with just the generated classes must spot any reusability opportunities by manual inspection.

It seems to me that one way to enhance the code-generation experience would be to have a new Serialization Attribute, e.g. XmlGroupAttribute. Such an attribute, when associated with a class (or fields of that type), would ensure that instances of the class got serialized correctly to XML inside the containing class.

I wonder whether there are other options that gives reusability of s in generated code? How about in .NET 2.0?




Detect XSD Code Generation Issues

Fri, 26 Nov 2004 15:17:00 GMT

The XSD.EXE command-line tool will generate .NET types from a set of XML Schema files. However, certain constructs in the XSD will result in faulty .NET code. In particular, elements with children that are not exclusively s are quite likely to have issues in the generated class. I found that the following XSLT stylesheet proves useful in flagging up potentially-troublesome Schema fragments. It's not perfect but it's better than scanning schema by eye. Xml Schema Code Generation Issue Report

Xml Schema Code Generation Issue Report

Target Namespace = {[...]




VS.NET 2003 Installation Woes

Wed, 04 Jun 2003 19:05:00 GMT

I finally got VS.NET 2003 working. It turns out that the DVD drive on my laptop has a firmware issue that means that an installation from DVD fails randomly.

OK - I copied the entire DVD to hard disk, then installed from the hard disk. Still, the installation was failing.

Next, I ran WinDiff, to compare the files on the DVD with those on the hard disk. Hmm, some checksum mismatches. So, I manually copied the dodgy files from the DVD, until WinDiff reports no differences.

Installation now succeeds! However, although VS.NET 2003 launches, the Splash Screen is blank, i.e. it does not show my name as the licensee nor does it display the icons for the features installed (C#, VB.NET, J# etc.). More worryingly, the IDE disappears from the screen if I invoke various IDE functionality:

1) Click an item on the Start Page

2) Try to debug a C# project that has breakpoints

3) Invoke the Macro Editor

Clutching at straws, I decided to run WinDiff again, this time comparing the Setup files on the hard disk with the runtime copies made by the installation process. Weird - there are some differences in various DLL files, including those that seem connected with the functionality listed above. Anyway, I manually copied all the mismatch files, then relaunched the IDE. All the same problems exist.

Finally, I ran the Repair option in the Setup, then rebooted for good luck. Bingo - this time it works and, so far, all the features I have tried function as expected.

Shame it took 4 weeks of banging my head on a wall to get there.




Explicitly Implicit

Thu, 01 May 2003 13:48:00 GMT

Here's a VB.NET quirk, to get the ball rolling:

In C#, you can say this:

Size size;

SizeF sizeF;

size = new Size(100, 100);

sizeF = size;

That's because the Size type has a Type Conversion defined for SizeF.

The documentation says:

In Visual Basic, you can use the conversion operators defined by a type, but you cannot define your own.

Here's an attempt to do the same thing in VB.NET:

Dim size As New Size(100,100)

Dim sizeF As SizeF

'These do not work - even with Option Strict Off

'sizeF = size

'sizeF = CType(size, SizeF)

'Call opImplicit explicitly - works!

sizeF = Size.opImplicit(size)

'Hey - fancy VB feature...

With size

    sizeF = New SizeF(.Width, .Height)

End With

Is this behaviour the same in VB.NET 2003?