Feb
11
Written by:
Michael Washington
2/11/2012 2:33 PM
Visual Studio LightSwitch allows you to create Collection Control extensions. A Collection Control extension allows you to specify the control that will display a Entity collection in LightSwitch. At the time this article is written, there is no official documentation on creating Collection Control extensions. The only example of a Collection Control that Microsoft provides is the Many-To-Many control (see: Using The Many-To-Many Control).
First note that the following are required in order to create LightSwitch extensions:
Create The Project
First, we create an extension project in Visual Studio.
We add a New Item to the .Lspkg project.
We add a Control to the project.
A number of files are created in the various projects in the solution, including a SimpleDataGrid.lsml file in the Metadata/Controls folder in the .Common project.
Change the code in the SimpleDataGrid.lsml file to the following code:
<?xml version="1.0" encoding="utf-8" ?>
<ModelFragment
xmlns="http://schemas.microsoft.com/LightSwitch/2010/xaml/model"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Control Name="SimpleDataGrid"
SupportedContentItemKind="Collection"
DesignerImageResource="SimpleDataGridExtension.SimpleDataGrid::ControlImage"
AttachedLabelSupport="DisplayedByContainer"
ChildView=":Summary">
<Control.Attributes>
<DisplayName Value="SimpleDataGrid" />
</Control.Attributes>
</Control>
</ModelFragment>
The key thing to note is that the SupportedContentItemKind is set to Collection.
Create The Control
Open the SimpleDataGrid.xaml file in the Presentation/Controls folder in the .Client project.
Remove the TextBox control.
Drag and drop the DataGrid control on the page (this will automatically add the required references to the project).
Set the DataGrid name to dgItems.
Open the SimpleDataGrid.xaml.cs file in the Presentation/Controls folder in the .Client project.
Change the using statements to the following:
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Collections;
using System.Windows.Data;
using System.Windows.Markup;
using System.ComponentModel.Composition;
using Microsoft.LightSwitch.Details;
using Microsoft.LightSwitch.Model;
using Microsoft.LightSwitch.Presentation;
using Microsoft.LightSwitch.Details.Client;
Note: in the following code, you will see wavy red lines when a code section does not have it’s remaining code inserted yet.
Add the following line to the constructor of the class:
this.SetBinding(ContentItemProperty, new Binding());
Add the following Dependency property:
/// <summary>
/// ContentItem property is bound to the IContentItem inside the
/// LightSwitch screen layout tree.
/// This is created to monitor if the DataContext of the control is changed.
/// </summary>
public IContentItem ContentItem
{
get { return (IContentItem)GetValue(ContentItemProperty); }
set { SetValue(ContentItemProperty, value); }
}
public static readonly DependencyProperty ContentItemProperty =
DependencyProperty.Register("ContentItem",
typeof(IContentItem), typeof(SimpleDataGrid),
new PropertyMetadata(OnContentItemChanged));
private static void OnContentItemChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
// When the ContentItem is changed, we reset the internal data binding
((SimpleDataGrid)d).SetContentDataBinding();
}
Finally insert the following code to fill the DataGrid:
private void SetContentDataBinding()
{
if (ContentItem != null)
{
// Get the collection that was passed to the control
IScreenCollectionProperty boundCollection =
(IScreenCollectionProperty)ContentItem.Screen.Details.Properties[ContentItem.BindingPath];
// Get the Model Members of the collection
var ModelMembers =
ContentItem.ChildItems[0].ResultingDataType.Members.OfType<IDataTypeMemberDefinition>();
// Loop thru each Model Members
foreach (var item in ModelMembers)
{
// Only use the properties that are EntityProperties
if (item.GetType().FullName == "Microsoft.LightSwitch.Model.Storage.EntityProperty")
{
// Create a DataGrid column
DataGridTextColumn objDataGridTextColumn = new DataGridTextColumn();
objDataGridTextColumn.Header = item.Name.ToString();
objDataGridTextColumn.Binding = new Binding(item.Name.ToString());
dgItems.Columns.Add(objDataGridTextColumn);
}
}
// Turns off Auto Generate Columns on the DastaGrid
dgItems.AutoGenerateColumns = false;
// Bind the DataGrid
dgItems.ItemsSource = (IEnumerable)boundCollection.Value;
}
}
Run The Project
We click on the .Vsix project…
We then Start Debugging. This will open another instance of Visual Studio.
We create or open a LightSwitch project and go into Properties.
We click on the Extensions tab and enable the extension.
When laying out a Screen we now have the option to select the SimpleDataGrid control for any collection.
When we run the application, we see the control.
Download Code
The LightSwitch project is available at http://lightswitchhelpwebsite.com/Downloads.aspx
Also See:
Microsoft Tutorials:
10 comment(s) so far...
Nice intro in collection extensions What if I want similar behavior as the LS datagrid, where the childview is a DataGridRow, allowing to specify, during design time which columns i want to show? Your example only allows the summary view. The internal implementation in the SetContentDataBinding method, should be slightly adapter to foreach trough the datagridrow collection and add columns accordingly. What I miss is the way how to allow a datagridrow as childview.
Do you have a pointer to further documentation on this.
By paul van bladel on
7/8/2012 5:04 AM
|
@paul van bladel - Perhaps it is betst to make a post in teh forums on this ste to better discuss this. i am unsure what you mean by child view and summary view. Each control is bound to a collection and shows that collection. There really isn't any more to it :)
By Michael Washington on
7/8/2012 5:08 AM
|
I am also trying to get the extension "catch" the childview of type "datagridrow" but having trouble to accomplish that. michael - what paul means is setting the extension datagrid columns through the lighswitch interface as you would with their built-in datagrid so you can choose the fields and set a display name. where your sample gets the datasource fieldnames without the ability to control it from the LS interface (by interface i mean GUI - the screens section)
any help will be much appreciated.
also, if you have any kind of forum to recommend i would like this very much
thank you for this website it does helped me a lot
By dekel on
3/10/2013 12:18 PM
|
@dekel - Unfortunately the extent of my experience on this subject is contained in this article. The best forum to go to is: http://social.msdn.microsoft.com/Forums/en-US/lsextensibility/threads
By Michael Washington on
3/10/2013 12:20 PM
|
@Michael - thank you for your reply. I will try to search this forum.
By dekel on
3/12/2013 9:50 PM
|
any update about how to make the ChildView as a DataGridRow (or a customer control) ?
By AAK on
6/27/2013 4:14 AM
|
@AAK - No.
By Michael Washington on
6/27/2013 4:14 AM
|
I am trying to create an extension for Lightswitch, and my extension is like a DataGrid control to visualize the Database.
The below hierarchy is my extension architecture.
XXX- Collection
->YYY - Group
->ZZZ - Value
I have defined some properties in XXX class, [Collection control] and it is viewing in property sheet, and i can able to do some manipulation while property changes [On..PropertyChanged method].
In the same way, I defined some properties in YYY[Group] and ZZZ classes[Value]. But nothing works.
I have raised this query in microsoft forum[ http://social.msdn.microsoft.com/Forums/vstudio/en-US/ac60e1c4-0ea1-4132-898d-a31ced21c8c1 ] also.
Any idea to get rid of this problem?
By Luojana on
7/7/2013 8:59 AM
|
@Luojana - Sorry, no.
By Michael Washington on
7/7/2013 9:21 AM
|
Thanks.
By Luojana on
7/7/2013 9:36 PM
|