Friday, 4 December 2009

Hiding Foreign Key or Children Columns Globally in Dynamic Data

A continuation of Hiding Foreign Key column Globally in Dynamic Data. Kharot here was asking in this tread Conditional display of Foreign key navigation for a way to do this same thing with the Children FieldTemplate (it took me a while to catch on Embarrassed) and so here it is, it’s basically the same as previouly written but just a few changes to the attribute and the Extension method used in the previous example.

/// <summary>
/// Checks if either the Foreign Key or 
/// Children navigation fields the are hidden.
/// </summary>
/// <param name="column">The current MetaColumn.</param>
/// <returns>
/// true if either the Foreign Key or Children 
/// navigation field are set to hidden at table level
/// </returns>
public static Boolean FkIsHidden(this MetaColumn column)
{
    var fkColumn = column as MetaForeignKeyColumn;
    if (fkColumn != null)
        return fkColumn.ParentTable.
            GetAttributeOrDefault<HideFKColumnAttribute>().
            ForeignKeyFieldIsHidden;
    
    var childrenColumn = column as MetaChildrenColumn;
    if (childrenColumn != null)
        return childrenColumn.ChildTable.
            GetAttributeOrDefault<HideFKColumnAttribute>().
            ChildrenFieldIsHidden;

    return false;
}

Listing 1 – the Extension method

All I’ve done here is test for the column being a hidden in either the Parent or Children tables.

/// <summary>
/// Hides the ForeignKey or Children Navigation Column
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class HideFKColumnAttribute : Attribute
{
    /// <summary>
    /// Gets or sets a value indicating whether [foreign key field hidden].
    /// </summary>
    /// <value>
    ///     <c>true</c> if [foreign key field hidden]; otherwise, <c>false</c>.
    /// </value>
    public Boolean ForeignKeyFieldIsHidden { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether [children field hidden].
    /// </summary>
    /// <value><c>true</c> if [children field hidden]; otherwise, <c>false</c>.</value>
    public Boolean ChildrenFieldIsHidden { get; set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="HideFKColumnAttribute"/> class.
    /// </summary>
    public HideFKColumnAttribute()
    {
        ForeignKeyFieldIsHidden = false;
        ChildrenFieldIsHidden = false;
    }
}

Listing 2 – HideFKColumnAttribute

Here I’ve added a new property and done a little refactoring to make things make sense and since it’s a Foreign Key relationship I’ve left the attribute with the same name.

[HideFKColumn(
    ForeignKeyFieldIsHidden = true,
    ChildrenFieldIsHidden = true)]
public partial class Employee
{
    // code omitted for brevity
}

Listing 3 – the metadata

I’ve made no changes to the IAutoFieldGenerator so things should just work, you can now hide the Foreign Key or Children columns globally.

Download

Remember to have fun coding Happy Wizzard

5 comments:

Dave said...

Hi Steve - thanks for the great post, saved me a substantial amount of effort. I'm not sure if this is of interest/value to you but I tweaked your GenerateFields method to only use LINQ for generating the list of DynamicField (as an exercise after reading Eric Lipperts blog post http://blogs.msdn.com/ericlippert/archive/2010/01/11/continuing-to-an-outer-loop.aspx).

public ICollection GenerateFields(Control control)
{
return (from column in table.Columns
orderby column.GetColumnOrder()
where column.Scaffold &&
!column.IsLongString &&
!column.FkIsHidden()
select new DynamicField()
{
DataField = column.Name
}).ToList();
}

Steve said...

Hi Dave, later version of my IAutoFieldGenerators do that, but good point I should have updated this one also.

Steve :D

Anonymous said...
This comment has been removed by a blog administrator.
Anonymous said...

Hi Steve,the code which in FkIsHidden method is fkColumn.ParentTable or childrenColumn.ChildTable,
not fkColumn.Table or childrenColumn.Table?

Steve said...

Hit there the answer is no :) no the idea is to reach out to the table the FK/Children Column is refering to to see if there is an attribute there saying it should be hidden. So if you have a table called Categories and apply the attribute where ever it is referenced it will be hidden depending on the attribute setting.

Steve.