c# - WPF DataType resolution for interface DataContexts -
this question has answer here:
i've set generic dialog window takes in viewmodel , title, display according window's xaml.
for example, code sets title , data context of window , shows it:
public void showwindow(object viewmodel, string title) { var win = new dialogwindow() { title = title, datacontext = viewmodel }; win.show(); } the window's codebehind contains nothing of relevance, xaml content presenter looks like:
<contentpresenter x:name="dialogpresenter" content="{binding}"> <contentpresenter.resources> <datatemplate datatype="{x:type i:imyinterface}" > <c:myinterfacescontrol/> </datatemplate> </contentpresenter.resources> </contentpresenter> the problem datatemplate doesn't fire, viewmodel passed in implementation of interface. however, want code detect whether viewmodel implements that, , use template accordingly.
i've thought of 1 or 2 ways around problem using converters, example checking whether implementation of converter parameter.
but there simpler way here?
edit: not same question suggested in comments (edit 2: that's gone); won't know interface type (many different ones may passed in), , instead have data context of type object work with.
datatemplate doesn't work types interfaces, should use concrete type.
if have interfaces defined
public interface ia { string { get; set; } } and concrete type implementing it:
public class aa : ia { public string { get; set; } } then following data template will not used, when passing new a();
<datatemplate datatype="{x:type local:ia}"> <textblock text="{binding a}" /> </datatemplate> instead see like
application.aa
solution 1
you can use concrete type , work:
<datatemplate datatype="{x:type local:aa}"> <textblock text="{binding a}" /> </datatemplate> solution 2
use property of interface type , bind (not concrete type), described in this answer.
note: can use same name of property return different interface (the 1 choose data template) in concrete types.
solution 3
you can use template selector. simple, give keys data template:
<datatemplate x:key="ia"> <textblock text="{binding a}" /> </datatemplate> and choose 1 use in code:
public class templateselector : datatemplateselector { public override datatemplate selecttemplate(object item, dependencyobject container) { if (item ia) return (datatemplate)((frameworkelement)container).findresource("ia"); return base.selecttemplate(item, container); } } contentcontrol has contenttemplateselector property, don't use contentpresenter this.
Comments
Post a Comment