Monday, March 26, 2012

listview drilldown into itself

There is cool example how to make drilldown from one listview to another athttp://www.wilcob.com/wilco/Default/161/showpost.aspx
It is really usefull in some cases, but what if you need results of second datasource under each item in listview? I tried simply copy second template inside first one, but this doesn't work:
<dataSourceid="productDataSource"serviceURL="Products.asmx"/>
<dataSourceid="commentsDataSource"serviceURL="Comments.asmx"/>
<listViewid="productListView" ...>
<bindings>
<bindingdataContext="productDataSource"dataPath="data"property="data"/>
</bindings>
[...]
<labelid="nameLabel">
<bindings>
<bindingdataPath="ProductName"property="text"/>
</bindings>
</label>
<buttonid="commentsButton">
<click>
<setPropertytarget="commentsDataSource"property="selectParameters"
propertyKey="ProductID">
<bindings>
<bindingdataPath="sender.dataContext.ProductID"property="value"/>
</bindings>
</setProperty>
<invokeMethodtarget="commentsDataSource"method="select"/>
</click>
</button>
<listViewid="commentsListView">
<bindings>
<bindingdataContext="commentsDataSource"dataPath="data"property="data"/>
</bindings>
</listView>
</listView>


Kick me back on path please...
Before you want to nest controls such as ListView inside a ListView,you should understand how templates work on a high level. Lets look ata basic template first (simplified):
HTML:
<div id="myListView">
</div>
<div class="template">
<div id="myListViewTemplate">
<div id="myListViewItemTemplate">
<span id="nameLabel"></span>
</div>
</div>
</div>
Atlas script:
<listView targetElement="myListView">
<layoutTemplate>
<template layoutElement="myListTemplate" />
</layoutTemplate>
<itemTemplate>
<template layoutElement="myListViewItemTemplate">
<label targetElement="nameLabel">...</label>
</template>
</itemTemplate>
</listView>
This is just a ListView which displays a label (span) for each item.When we define a template, such as the item template, we can definewhat kind of controls the elements inside the context of that templateis. In this example we say that the element "nameLabel", inside theelement "myListViewItemTemplate", is a label.
When you bind the listview against for example a datasource with 2items, Atlas will clone the "myListViewItemTemplate" element to createan item instance that will be added to the DOM. Atlas will look at yourAtlas definitions and instantiate and initialize the componentsassociated with the elements inside this item instance.
In your case, you should do exactly the same with a nested listview as you do with a label.
That is, you should first define the nested listview inside the parentlistview's item template. The HTML for a listview with a nestedlistview could look something like this:
<div id="myListView">
</div>
<div class="template">
<div id="myListViewTemplate">
<div id="myListViewItemTemplate">
<span id="myNameLabel"></span>
<div id="myNestedListView">
</div>
<div class="template">
<div id="myNestedListViewTemplate">
<div id="myNestedListViewItemTemplate">
<span id="myNestedNameLabel"></span>
</div>
</div>
</div>

</div>
</div>
</div>
And the Atlas code would then look something like:
<listView targetElement="myListView" ...>
<layoutTemplate>
<template layoutElement="myListTemplate" />
</layoutTemplate>
<itemTemplate>
<template layoutElement="myListViewItemTemplate">
<label targetElement="nameLabel">...</label>
<listView targetElement="" ...>
<layoutTemplate>
<template layoutElement="myNestedListViewTemplate" />
</layoutTemplate>
<itemTemplate>
<template layoutElement="myNestedListViewItemTemplate">
<label targetElement="myNestedNameLabel">...</label>
</template>
</itemTemplate>
</listView>
</template>
</itemTemplate>
</listView>
I haven't actually tried this, but this should work. Please let me know if this makes sense.

Ok, I got it theoretically, I think. When I copied code from your previous master/detail example, it repeats result of query behind under each element of original listview as you can see onhttp://hidef.asp2.cz/default2.aspx (maybe only in code, it sometimes doesnt work) I think in this scenario I must do other type of data keying then you have in your master/detail example. There should be way to bind that nested listview on load with automatic=false and then do only evaluatein, but I didn't find way how to bind parameter of datasource for nested one from datasource of master one like:

<dataSourceid="commentsDS"runat="server" serviceUrl="comments.asmx">
<bindings>
<binding dataContext="??something??" dataPath="text" property="selectParameters" propertyKey="topic"/>
</bindings>
</dataSource>
...
<listView targetElement="CommentsListView" itemTemplateParentElementId="CommentsListViewTemplate" propertyChanged="onChange">
<bindings>
<binding dataContext="commentsDS" dataPath="data" property="data"/>
</bindings>
<layoutTemplate>
<template layoutElement="CommentsListViewTemplate" />
</layoutTemplate>
<itemTemplate>
<template layoutElement="CommentsListViewItemTemplate">
<label targetElement="commentText">
<bindings>
<binding dataPath="c_text" property="text"/>
</bindings>
</label>
</template>
</itemTemplate>
</listView>


I think your code looks correct. You should leave the data contextempty, and set the dataPath to for example "NewsID", which would be aproperty of the dataitem inside the outer listview. I think that wouldwork.

I don't know if I set right dataPath and if code for setting property is ok, but it doesn't work. You can see what I tried on default.aspx. I'll continue trying...but it looks I'm running in circle again.
You should declare the comments data source _inside_ the itemtemplateof the listview, in which you have placed the nested listview.

It doesnt workSad [:(]
I tried set property named newsID and moved datasource first. Then I tried to make dummy control with this id bounded as text and setting datasource parameter by this. Nothing of this works.
If I got it, atlas creates datasource instance for each item in listview, so I tried simply parametrize by binding this ID directly, as it is on my page now. I don't know why it doesn't work,but I also don't know if it is a good idea to let it work in this way. This mechanism should work fine on my simple page rendering engine with few items. But when I'm tried in classic asp.net create master/detail in this fashion, it was unusable. I solved it by binding to dataset with two related datatables and detail repeater was defined as:
<asp:repeater id="childRepeater" datasource='<%# ((DataRowView)Container.DataItem).Row.GetChildRows("myrelation") %>' runat="server">
Are there ..or will be there in future...techniques in atlas which can work same way?

You can see a demo of a nested listview using atlas athttp://www.wilcob.com/atlasnestedlistview. The source for this demo canbe downloaded fromhttp://www.wilcob.com/wilco/Downloads/Programming/AtlasNestedListView.zip.
As you can see, I currently use a button to invoke the nestedDataSource. I can't currently think of a way that would automagicallylet it select data from the service once it is created, withoutmodifying atlas sources or adding a custom control.
Update: fixed links.

It was close..huh..I had dataContext="newsNameLabel" dataPath="ID" instead of dataContext="newsNameLabel" dataPath="dataContext.ID" in one of my testversions. Thanks

No comments:

Post a Comment