wsick / Fayde

Inspired by Silverlight; XAML engine using Javascript and rendering to the HTML5 Canvas.
MIT License
189 stars 27 forks source link

Implement implicit DataType DataTemplates. #255

Open BSick7 opened 8 years ago

BSick7 commented 8 years ago

DataTemplate.DataType is parsed and loaded; however, there is no selection process happening. Test cases were merged from PR #254

BSick7 commented 8 years ago

@hypersw I'm concerned about the negative effect to performance this may have on a ListBox. As I see it, every time an item needs templated and has no template; one would have to crawl up the tree scanning Resources for a DataTemplate that matches.

hypersw commented 8 years ago

In the big WPF, it would create a resource key object DataTemplateKey from the type of viewmodel to be templated, and then it's a mere resource lookup by a key, which is no worse than looking up dynamic resource or static resource references in the elements. Also a few last hits could be cached in the templating engine of the itemscontrol.

BSick7 commented 8 years ago

That isn't a huge hit for for most operations as the resource chain is cascaded through the xaml load process. Since implicit data templates are active instead of passive, only an explicit template would prevent tree scan. Ideally, a list box would have a hint as to when to tree scan.

As an alternative, would it work if a list box had a template selector with implicit data templates. This would put the list box into active mode only by developer's cue.

cc @Ronmenator

hypersw commented 8 years ago

Just intuitively, that shan't be much different from binding a dynamic resource reference expression at a time later than load. Maybe even a static if this happens when a new itemscontrol item is added and a template is rendered for it, with a resource reference expression which resolves into a resource defined not in the template but somewhere in the tree of the control. Wouldn't that be the same lookup?

I'd have a look into how the big WPF handles this.

Is there a need in additional cues? If the itemscontrol is able to template its items passively (them being ui elements already, or having an explicit data template, or whatever), then we're passive and fast. If the template were not found, then either it's a bug in the markup, or the template is expected to be type-bound, anyway an active lookup would be OK to do, I suppose. I guess this only becomes a problem if done for lots of items in a row, but usually there would be one or a few different item types, so a simple caching would make this negligible. What's also bad about additional cues is that they are different from how WPF works and aren't straightforward.

Anyway this won't make old scenarios slower, would it?

Ronmenator commented 8 years ago

In iPRO we use implicit templating for everything and have not seen a major issue with performance.

image

In this picture you will notice the 'Telerik style' RadGridView control we created, this use a Template Chooser; Then everything you see on that screen is driven by implicit templates to determine which view and ViewModel to combine.

hypersw commented 8 years ago

Is this WPF, SL, Fayde?

As of the big WPF, most of the views in ReSharper are bound to viewmodels via type-based template binding, with lookup ending up in the application-wide resource dictionary. When the application is composable and uses inversion of control, the parent view cannot know the all-embracing list of the child views it would home at runtime. This has to be a runtime-pluggable list, and with the ways of WPF this most naturally comes as type-bound data templates.

The only perf issue so far is that the ResourceDictionary cannot work the pull-way, but has to be explicitly pushed with all the known views on startup, which causes to load some unneeded DLLs.

hypersw commented 8 years ago

The code is supposed to be in the _GetContentTemplate function in ContentPresenter.ts, but the magic would not happen.

hypersw commented 8 years ago

Okay, so I have debugged this down to some point. Looks like the ListBox items binding case, as in the demo, is generally supported in the framework, but is prevented due to a bug (or so it looks).

In ContentPresenterNode class, the _GetContentTemplate has the following logic:

  1. Use the ContentTemplate, if set explicitly on this presenter.
  2. Look up a template in resources by the data type.
  3. Fallback to the default template, which binds to the object itself.

Should work, but! ItemsControl class UpdateContainerTemplate function always assigns a ContentTemplate to the ContentPresenter. Seemingly, this is expected to make the DisplayMemberPath work if specified, which implies on the corresponding template; but this also sets a dummy template if all props are null.

What about setting it only if DisplayMemberPath is given? @BSick7 I'd try a PR.