Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind DataTemplate datatype to interface?

I am writing a composite loosely coupled MVVM WPF application and child VMs in a parent VM are interfaces rather than class instances, e.g.

public IChildViewModel { get; set; } 

Now how do I render this property using a DataTemplate? like:

<DataTemplate DataType="{x:Type contracts:IChildViewModel}"> 

I understand due to the nature of interfaces (multiple inheritance etc.) WPF does not allow this direct binding. But as interfaces should be used widely in loosely coupled applications, is there any workaround to bind DataTemplate to interfaces? Thanks.

like image 619
Charlie Avatar asked Feb 22 '13 11:02

Charlie


People also ask

What is DataTemplate?

A data template can contain elements that are each bound to a data property along with additional markup that describes layout, color and other appearance. DataTemplate is, basically, used to specify the appearance of data displayed by a control not the appearance of the control itself.

What is difference between a control template and DataTemplate in WPF?

A ControlTemplate will generally only contain TemplateBinding expressions, binding back to the properties on the control itself, while a DataTemplate will contain standard Binding expressions, binding to the properties of its DataContext (the business/domain object or view model).

What is WPF item template?

WPF provides various templates for customization of controls. WPF ListView ItemTemplate is in one of these. ItemTemplate of ListView is useful when we have to change the visual presentation of bound data objects.


2 Answers

You can bind to interfaces by telling wpf explicitly that you are binding to an interface field:

(Please note that ViewModelBase is simply a base-class that implements the INotifyPropertyChanged interface)

public class Implementation : ViewModelBase, IInterface {     private string textField;      public string TextField     {         get         {             return textField;         }         set         {             if (value == textField) return;             textField = value;             OnPropertyChanged();         }     } }  public interface IInterface {     string TextField { get; set; } } 

Then on the ViewModel:

private IInterface interfaceContent; public IInterface InterfaceContent {     get { return interfaceContent; } } 

And finally the Xaml that makes it possible:

<ContentControl Grid.Row="1" Grid.Column="0" Content="{Binding InterfaceContent}">     <ContentControl.ContentTemplate>         <DataTemplate DataType="{x:Type viewModels:IInterface}">             <TextBox Text="{Binding Path=(viewModels:IInterface.TextField)}"/>         </DataTemplate>     </ContentControl.ContentTemplate> </ContentControl> 

As you can see, the binding refers explicitly to the 'IInterface' definiton.

like image 123
t0yk4t Avatar answered Oct 02 '22 07:10

t0yk4t


It seems that using a DataTemplateSelectoris the way to go in such situations.

like image 42
Natxo Avatar answered Oct 02 '22 07:10

Natxo