How to properly bind multiple ViewModels when using DataTemplateSelector [duplicate]












0















This question already has an answer here:




  • How to use DataTemplateSelector with ContentControl to display different controls based on the view-model?

    2 answers




I'm trying to write a simple dialog that would accept a value in a SpinEdit or a text in a TextEdit. I'm using multiple VMs and I made a selector that should view a proper control based on the logic in the c++/cli file.



XAML:



       xmlns:local="clr-namespace:asd"
Title="{Binding Path=Title, Mode=OneTime}"

<dx:DXWindow.Resources>

<DataTemplate x:Key="TInputValueVM" DataType="{x:Type local:TInputValueVM}">
<dxe:SpinEdit Height="23" Width="200"
Text="{Binding Value, Mode=TwoWay}"
Mask="{Binding Mask, Mode=OneWay}"
MaxLength="{Binding Path=InputLength}" />

</DataTemplate>

<DataTemplate x:Key="TInputTextVM" DataType="{x:Type local:TInputTextVM}">
<dxe:TextEdit Height="23" Width="200"
Text="{Binding Value, Mode=TwoWay}"
MaskType="RegEx" Mask="{Binding Mask, Mode=OneWay}"
MaxLength="{Binding Path=InputLength}"/>
</DataTemplate>

<local:PropertyDataTemplateSelector x:Key="templateSelector"
DataTemplate_Value="{StaticResource TInputValueVM}"
DataTemplate_Text="{StaticResource TInputTextVM}" />

</dx:DXWindow.Resources>


<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<StackPanel Grid.Row="0" >
<Label x:Uid="Label" MinHeight="24" MinWidth="60" Content="Value" />
<ContentControl Content="{Binding Path=Whoami}" ContentTemplateSelector="{StaticResource templateSelector}" />
</StackPanel>

<StackPanel Grid.Row="1" x:Uid="OKCancel_Buttons" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Button Height="23" x:Name="OK_Button" Click="OK_Click" Content="OK" IsDefault="True" HorizontalAlignment="Right" MinWidth="95" />
<Button Height="23" x:Name="Cancel_Button" Click="Cancel_Click" Content="Cancel" HorizontalAlignment="Right" MinWidth="95" />
</StackPanel>

</Grid>


In c# I have a base VM and two VMS that extend it, one for values and one for text. The rest of the properties stay the same.



C#



namespace asd
{
public class TInputBaseVM : ViewModelBase
{
private string m_sTitle;
private string m_sMask;
private int m_nInputLenght;
private string m_sWhoami;

public TInputBaseVM(string A_sTitle, string A_sMask, int A_nInputLength)
{
m_sTitle = A_sTitle;
m_sMask = A_sMask;
m_nInputLenght = A_nInputLength;
}

protected string Title
{
get { return m_sTitle; }
set { SetProperty(ref m_sTitle, value, () => Title); }
}
protected string Mask
{
get { return m_sMask; }
set { SetProperty(ref m_sMask, value, () => Mask); }
}

protected int InputLength
{
get { return m_nInputLenght; }
set { SetProperty(ref m_nInputLenght, value, () => InputLength); }
}

protected string Whoami
{
get { return m_sWhoami; }
set { SetProperty(ref m_sWhoami, value, () => Whoami); }
}
}

public class TInputValueVM : TInputBaseVM
{
public TInputValueVM(string A_sTitle, string A_sMask, int A_nInputLength, double A_nValue) : base(A_sTitle, A_sMask, A_nInputLength)
{
Value = A_nValue;
Whoami = "Value";
}

private double m_nValue;
public double Value
{
get { return m_nValue; }
set { SetProperty(ref m_nValue, value, () => Value); }
}
}

public class TInputTextVM : TInputBaseVM
{
public TInputTextVM(string A_sTitle, string A_sMask, int A_nInputLength, string A_sValue) : base(A_sTitle, A_sMask, A_nInputLength)
{
Value = A_sValue;
Whoami = "Text";
}

private string m_sValue;
public string Value
{
get { return m_sValue; }
set { SetProperty(ref m_sValue, value, () => Value); }
}
}

public class PropertyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate DataTemplate_Value { get; set; }
public DataTemplate DataTemplate_Text { get; set; }

public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var selector = item as string;

if(selector == "Value")
return DataTemplate_Value;
return DataTemplate_Text;
}
}

}


In c++/cli I create an object of a proper VM and I'd like the WPF to automatically update the view to either spinedit or textedit, however I'm not sure how to properly bind the properties from the C#. If I explicitly type 'Value' in the Content property of the ContentControl then it displays the spinEdit but I don't know how to bind it so it automatically takes the correct property.



EDIT: I'm adding c++/cli code to show how I choose different VMs



C++/cli:



bool TSignalNumberPositionDialogCLR::StartDialog(TSignalNumberPositionSupport& A_Attributes, HWND A_hwndParent, LPTSTR String)
{
try
{
TInputValueVM ^oExchange_Value;
TInputTextVM ^oExchange_Text;

int inputFormat = A_Attributes.GetInputFormat();

if(inputFormat)
oExchange_Text = gcnew TInputTextVM(gcnew System::String(A_Attributes.GetTitle()), gcnew System::String(A_Attributes.GetMask()),
A_Attributes.GetInputLength(), gcnew System::String(A_Attributes.GetInitialText()));
else
oExchange_Value = gcnew TInputValueVM(gcnew System::String(A_Attributes.GetTitle()), gcnew System::String(A_Attributes.GetMask()),
A_Attributes.GetInputLength(), A_Attributes.GetInitialValue());


Dialogs::TSignalNumberPositionDialog^ dialog = gcnew Dialogs::TSignalNumberPositionDialog();

if(inputFormat)
dialog->DataContext = oExchange_Text;
else
dialog->DataContext = oExchange_Value;

dialog->ShowDialog();

if(dialog->DialogResult)
{
CString nValue;

if(inputFormat)
nValue = oExchange_Text->Value;
else
nValue = ((Decimal)oExchange_Value->Value).ToString("F2", CultureInfo::InvariantCulture);

A_Attributes.UpdateValue(nValue, String, A_Attributes.GetInputLength());
return true;
}

return false;
}
catch(Exception^ e)
{
e;
}
}


based on the 'inputFormat' variable I want to display different controls in the dialog.



EDIT: Based on @Clemens comments I got rid of the selector sectionand the x:Key property in the DataTemplates. I changed the content opf the Content property to Content="{Binding}" and it somehow works. The moment I create a VM it selects the correct one.










share|improve this question















marked as duplicate by Clemens c#
Users with the  c# badge can single-handedly close c# questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 13 '18 at 11:27


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.















  • Content="{Binding Path=Whoami}" and the ContentTemplateSelector don't seem to make sense. When you assign or bind an object to the Content property of a ContentControl, the control automatically select an appropriate ContentTemplate via the DataTemplate's DataType, i.e. one that matches the Content type.
    – Clemens
    Nov 13 '18 at 9:35












  • @Clemens So what would I need to do? delete the whole selector section and bind what exactly in the Content property or ContentControl?
    – bananeeek
    Nov 13 '18 at 9:52










  • As said, the ContentTemplate is automatically selected according to the type of the Content. If you bind Content to an object of type MyClass, the DataTemplate with DataType"{x:Type local:MyClass}" and without a x:Key is chosen.
    – Clemens
    Nov 13 '18 at 10:05












  • @Clemens But I have two VMs and two DataTemplates. If I define one DT as DataType"{x:Type local:TInputValueVM}" and the second DT as DataType"(x:Type local:TInputTextVM}" then what do I bind the ControlContent's Content property to?
    – bananeeek
    Nov 13 '18 at 10:16










  • The appropriate view model, for example a property CurrentVM like Content="{Binding CurrentVM}". CurrentVM returns either a TInputValueVM or a TInputTextVM.
    – Clemens
    Nov 13 '18 at 10:29
















0















This question already has an answer here:




  • How to use DataTemplateSelector with ContentControl to display different controls based on the view-model?

    2 answers




I'm trying to write a simple dialog that would accept a value in a SpinEdit or a text in a TextEdit. I'm using multiple VMs and I made a selector that should view a proper control based on the logic in the c++/cli file.



XAML:



       xmlns:local="clr-namespace:asd"
Title="{Binding Path=Title, Mode=OneTime}"

<dx:DXWindow.Resources>

<DataTemplate x:Key="TInputValueVM" DataType="{x:Type local:TInputValueVM}">
<dxe:SpinEdit Height="23" Width="200"
Text="{Binding Value, Mode=TwoWay}"
Mask="{Binding Mask, Mode=OneWay}"
MaxLength="{Binding Path=InputLength}" />

</DataTemplate>

<DataTemplate x:Key="TInputTextVM" DataType="{x:Type local:TInputTextVM}">
<dxe:TextEdit Height="23" Width="200"
Text="{Binding Value, Mode=TwoWay}"
MaskType="RegEx" Mask="{Binding Mask, Mode=OneWay}"
MaxLength="{Binding Path=InputLength}"/>
</DataTemplate>

<local:PropertyDataTemplateSelector x:Key="templateSelector"
DataTemplate_Value="{StaticResource TInputValueVM}"
DataTemplate_Text="{StaticResource TInputTextVM}" />

</dx:DXWindow.Resources>


<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<StackPanel Grid.Row="0" >
<Label x:Uid="Label" MinHeight="24" MinWidth="60" Content="Value" />
<ContentControl Content="{Binding Path=Whoami}" ContentTemplateSelector="{StaticResource templateSelector}" />
</StackPanel>

<StackPanel Grid.Row="1" x:Uid="OKCancel_Buttons" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Button Height="23" x:Name="OK_Button" Click="OK_Click" Content="OK" IsDefault="True" HorizontalAlignment="Right" MinWidth="95" />
<Button Height="23" x:Name="Cancel_Button" Click="Cancel_Click" Content="Cancel" HorizontalAlignment="Right" MinWidth="95" />
</StackPanel>

</Grid>


In c# I have a base VM and two VMS that extend it, one for values and one for text. The rest of the properties stay the same.



C#



namespace asd
{
public class TInputBaseVM : ViewModelBase
{
private string m_sTitle;
private string m_sMask;
private int m_nInputLenght;
private string m_sWhoami;

public TInputBaseVM(string A_sTitle, string A_sMask, int A_nInputLength)
{
m_sTitle = A_sTitle;
m_sMask = A_sMask;
m_nInputLenght = A_nInputLength;
}

protected string Title
{
get { return m_sTitle; }
set { SetProperty(ref m_sTitle, value, () => Title); }
}
protected string Mask
{
get { return m_sMask; }
set { SetProperty(ref m_sMask, value, () => Mask); }
}

protected int InputLength
{
get { return m_nInputLenght; }
set { SetProperty(ref m_nInputLenght, value, () => InputLength); }
}

protected string Whoami
{
get { return m_sWhoami; }
set { SetProperty(ref m_sWhoami, value, () => Whoami); }
}
}

public class TInputValueVM : TInputBaseVM
{
public TInputValueVM(string A_sTitle, string A_sMask, int A_nInputLength, double A_nValue) : base(A_sTitle, A_sMask, A_nInputLength)
{
Value = A_nValue;
Whoami = "Value";
}

private double m_nValue;
public double Value
{
get { return m_nValue; }
set { SetProperty(ref m_nValue, value, () => Value); }
}
}

public class TInputTextVM : TInputBaseVM
{
public TInputTextVM(string A_sTitle, string A_sMask, int A_nInputLength, string A_sValue) : base(A_sTitle, A_sMask, A_nInputLength)
{
Value = A_sValue;
Whoami = "Text";
}

private string m_sValue;
public string Value
{
get { return m_sValue; }
set { SetProperty(ref m_sValue, value, () => Value); }
}
}

public class PropertyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate DataTemplate_Value { get; set; }
public DataTemplate DataTemplate_Text { get; set; }

public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var selector = item as string;

if(selector == "Value")
return DataTemplate_Value;
return DataTemplate_Text;
}
}

}


In c++/cli I create an object of a proper VM and I'd like the WPF to automatically update the view to either spinedit or textedit, however I'm not sure how to properly bind the properties from the C#. If I explicitly type 'Value' in the Content property of the ContentControl then it displays the spinEdit but I don't know how to bind it so it automatically takes the correct property.



EDIT: I'm adding c++/cli code to show how I choose different VMs



C++/cli:



bool TSignalNumberPositionDialogCLR::StartDialog(TSignalNumberPositionSupport& A_Attributes, HWND A_hwndParent, LPTSTR String)
{
try
{
TInputValueVM ^oExchange_Value;
TInputTextVM ^oExchange_Text;

int inputFormat = A_Attributes.GetInputFormat();

if(inputFormat)
oExchange_Text = gcnew TInputTextVM(gcnew System::String(A_Attributes.GetTitle()), gcnew System::String(A_Attributes.GetMask()),
A_Attributes.GetInputLength(), gcnew System::String(A_Attributes.GetInitialText()));
else
oExchange_Value = gcnew TInputValueVM(gcnew System::String(A_Attributes.GetTitle()), gcnew System::String(A_Attributes.GetMask()),
A_Attributes.GetInputLength(), A_Attributes.GetInitialValue());


Dialogs::TSignalNumberPositionDialog^ dialog = gcnew Dialogs::TSignalNumberPositionDialog();

if(inputFormat)
dialog->DataContext = oExchange_Text;
else
dialog->DataContext = oExchange_Value;

dialog->ShowDialog();

if(dialog->DialogResult)
{
CString nValue;

if(inputFormat)
nValue = oExchange_Text->Value;
else
nValue = ((Decimal)oExchange_Value->Value).ToString("F2", CultureInfo::InvariantCulture);

A_Attributes.UpdateValue(nValue, String, A_Attributes.GetInputLength());
return true;
}

return false;
}
catch(Exception^ e)
{
e;
}
}


based on the 'inputFormat' variable I want to display different controls in the dialog.



EDIT: Based on @Clemens comments I got rid of the selector sectionand the x:Key property in the DataTemplates. I changed the content opf the Content property to Content="{Binding}" and it somehow works. The moment I create a VM it selects the correct one.










share|improve this question















marked as duplicate by Clemens c#
Users with the  c# badge can single-handedly close c# questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 13 '18 at 11:27


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.















  • Content="{Binding Path=Whoami}" and the ContentTemplateSelector don't seem to make sense. When you assign or bind an object to the Content property of a ContentControl, the control automatically select an appropriate ContentTemplate via the DataTemplate's DataType, i.e. one that matches the Content type.
    – Clemens
    Nov 13 '18 at 9:35












  • @Clemens So what would I need to do? delete the whole selector section and bind what exactly in the Content property or ContentControl?
    – bananeeek
    Nov 13 '18 at 9:52










  • As said, the ContentTemplate is automatically selected according to the type of the Content. If you bind Content to an object of type MyClass, the DataTemplate with DataType"{x:Type local:MyClass}" and without a x:Key is chosen.
    – Clemens
    Nov 13 '18 at 10:05












  • @Clemens But I have two VMs and two DataTemplates. If I define one DT as DataType"{x:Type local:TInputValueVM}" and the second DT as DataType"(x:Type local:TInputTextVM}" then what do I bind the ControlContent's Content property to?
    – bananeeek
    Nov 13 '18 at 10:16










  • The appropriate view model, for example a property CurrentVM like Content="{Binding CurrentVM}". CurrentVM returns either a TInputValueVM or a TInputTextVM.
    – Clemens
    Nov 13 '18 at 10:29














0












0








0








This question already has an answer here:




  • How to use DataTemplateSelector with ContentControl to display different controls based on the view-model?

    2 answers




I'm trying to write a simple dialog that would accept a value in a SpinEdit or a text in a TextEdit. I'm using multiple VMs and I made a selector that should view a proper control based on the logic in the c++/cli file.



XAML:



       xmlns:local="clr-namespace:asd"
Title="{Binding Path=Title, Mode=OneTime}"

<dx:DXWindow.Resources>

<DataTemplate x:Key="TInputValueVM" DataType="{x:Type local:TInputValueVM}">
<dxe:SpinEdit Height="23" Width="200"
Text="{Binding Value, Mode=TwoWay}"
Mask="{Binding Mask, Mode=OneWay}"
MaxLength="{Binding Path=InputLength}" />

</DataTemplate>

<DataTemplate x:Key="TInputTextVM" DataType="{x:Type local:TInputTextVM}">
<dxe:TextEdit Height="23" Width="200"
Text="{Binding Value, Mode=TwoWay}"
MaskType="RegEx" Mask="{Binding Mask, Mode=OneWay}"
MaxLength="{Binding Path=InputLength}"/>
</DataTemplate>

<local:PropertyDataTemplateSelector x:Key="templateSelector"
DataTemplate_Value="{StaticResource TInputValueVM}"
DataTemplate_Text="{StaticResource TInputTextVM}" />

</dx:DXWindow.Resources>


<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<StackPanel Grid.Row="0" >
<Label x:Uid="Label" MinHeight="24" MinWidth="60" Content="Value" />
<ContentControl Content="{Binding Path=Whoami}" ContentTemplateSelector="{StaticResource templateSelector}" />
</StackPanel>

<StackPanel Grid.Row="1" x:Uid="OKCancel_Buttons" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Button Height="23" x:Name="OK_Button" Click="OK_Click" Content="OK" IsDefault="True" HorizontalAlignment="Right" MinWidth="95" />
<Button Height="23" x:Name="Cancel_Button" Click="Cancel_Click" Content="Cancel" HorizontalAlignment="Right" MinWidth="95" />
</StackPanel>

</Grid>


In c# I have a base VM and two VMS that extend it, one for values and one for text. The rest of the properties stay the same.



C#



namespace asd
{
public class TInputBaseVM : ViewModelBase
{
private string m_sTitle;
private string m_sMask;
private int m_nInputLenght;
private string m_sWhoami;

public TInputBaseVM(string A_sTitle, string A_sMask, int A_nInputLength)
{
m_sTitle = A_sTitle;
m_sMask = A_sMask;
m_nInputLenght = A_nInputLength;
}

protected string Title
{
get { return m_sTitle; }
set { SetProperty(ref m_sTitle, value, () => Title); }
}
protected string Mask
{
get { return m_sMask; }
set { SetProperty(ref m_sMask, value, () => Mask); }
}

protected int InputLength
{
get { return m_nInputLenght; }
set { SetProperty(ref m_nInputLenght, value, () => InputLength); }
}

protected string Whoami
{
get { return m_sWhoami; }
set { SetProperty(ref m_sWhoami, value, () => Whoami); }
}
}

public class TInputValueVM : TInputBaseVM
{
public TInputValueVM(string A_sTitle, string A_sMask, int A_nInputLength, double A_nValue) : base(A_sTitle, A_sMask, A_nInputLength)
{
Value = A_nValue;
Whoami = "Value";
}

private double m_nValue;
public double Value
{
get { return m_nValue; }
set { SetProperty(ref m_nValue, value, () => Value); }
}
}

public class TInputTextVM : TInputBaseVM
{
public TInputTextVM(string A_sTitle, string A_sMask, int A_nInputLength, string A_sValue) : base(A_sTitle, A_sMask, A_nInputLength)
{
Value = A_sValue;
Whoami = "Text";
}

private string m_sValue;
public string Value
{
get { return m_sValue; }
set { SetProperty(ref m_sValue, value, () => Value); }
}
}

public class PropertyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate DataTemplate_Value { get; set; }
public DataTemplate DataTemplate_Text { get; set; }

public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var selector = item as string;

if(selector == "Value")
return DataTemplate_Value;
return DataTemplate_Text;
}
}

}


In c++/cli I create an object of a proper VM and I'd like the WPF to automatically update the view to either spinedit or textedit, however I'm not sure how to properly bind the properties from the C#. If I explicitly type 'Value' in the Content property of the ContentControl then it displays the spinEdit but I don't know how to bind it so it automatically takes the correct property.



EDIT: I'm adding c++/cli code to show how I choose different VMs



C++/cli:



bool TSignalNumberPositionDialogCLR::StartDialog(TSignalNumberPositionSupport& A_Attributes, HWND A_hwndParent, LPTSTR String)
{
try
{
TInputValueVM ^oExchange_Value;
TInputTextVM ^oExchange_Text;

int inputFormat = A_Attributes.GetInputFormat();

if(inputFormat)
oExchange_Text = gcnew TInputTextVM(gcnew System::String(A_Attributes.GetTitle()), gcnew System::String(A_Attributes.GetMask()),
A_Attributes.GetInputLength(), gcnew System::String(A_Attributes.GetInitialText()));
else
oExchange_Value = gcnew TInputValueVM(gcnew System::String(A_Attributes.GetTitle()), gcnew System::String(A_Attributes.GetMask()),
A_Attributes.GetInputLength(), A_Attributes.GetInitialValue());


Dialogs::TSignalNumberPositionDialog^ dialog = gcnew Dialogs::TSignalNumberPositionDialog();

if(inputFormat)
dialog->DataContext = oExchange_Text;
else
dialog->DataContext = oExchange_Value;

dialog->ShowDialog();

if(dialog->DialogResult)
{
CString nValue;

if(inputFormat)
nValue = oExchange_Text->Value;
else
nValue = ((Decimal)oExchange_Value->Value).ToString("F2", CultureInfo::InvariantCulture);

A_Attributes.UpdateValue(nValue, String, A_Attributes.GetInputLength());
return true;
}

return false;
}
catch(Exception^ e)
{
e;
}
}


based on the 'inputFormat' variable I want to display different controls in the dialog.



EDIT: Based on @Clemens comments I got rid of the selector sectionand the x:Key property in the DataTemplates. I changed the content opf the Content property to Content="{Binding}" and it somehow works. The moment I create a VM it selects the correct one.










share|improve this question
















This question already has an answer here:




  • How to use DataTemplateSelector with ContentControl to display different controls based on the view-model?

    2 answers




I'm trying to write a simple dialog that would accept a value in a SpinEdit or a text in a TextEdit. I'm using multiple VMs and I made a selector that should view a proper control based on the logic in the c++/cli file.



XAML:



       xmlns:local="clr-namespace:asd"
Title="{Binding Path=Title, Mode=OneTime}"

<dx:DXWindow.Resources>

<DataTemplate x:Key="TInputValueVM" DataType="{x:Type local:TInputValueVM}">
<dxe:SpinEdit Height="23" Width="200"
Text="{Binding Value, Mode=TwoWay}"
Mask="{Binding Mask, Mode=OneWay}"
MaxLength="{Binding Path=InputLength}" />

</DataTemplate>

<DataTemplate x:Key="TInputTextVM" DataType="{x:Type local:TInputTextVM}">
<dxe:TextEdit Height="23" Width="200"
Text="{Binding Value, Mode=TwoWay}"
MaskType="RegEx" Mask="{Binding Mask, Mode=OneWay}"
MaxLength="{Binding Path=InputLength}"/>
</DataTemplate>

<local:PropertyDataTemplateSelector x:Key="templateSelector"
DataTemplate_Value="{StaticResource TInputValueVM}"
DataTemplate_Text="{StaticResource TInputTextVM}" />

</dx:DXWindow.Resources>


<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<StackPanel Grid.Row="0" >
<Label x:Uid="Label" MinHeight="24" MinWidth="60" Content="Value" />
<ContentControl Content="{Binding Path=Whoami}" ContentTemplateSelector="{StaticResource templateSelector}" />
</StackPanel>

<StackPanel Grid.Row="1" x:Uid="OKCancel_Buttons" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Button Height="23" x:Name="OK_Button" Click="OK_Click" Content="OK" IsDefault="True" HorizontalAlignment="Right" MinWidth="95" />
<Button Height="23" x:Name="Cancel_Button" Click="Cancel_Click" Content="Cancel" HorizontalAlignment="Right" MinWidth="95" />
</StackPanel>

</Grid>


In c# I have a base VM and two VMS that extend it, one for values and one for text. The rest of the properties stay the same.



C#



namespace asd
{
public class TInputBaseVM : ViewModelBase
{
private string m_sTitle;
private string m_sMask;
private int m_nInputLenght;
private string m_sWhoami;

public TInputBaseVM(string A_sTitle, string A_sMask, int A_nInputLength)
{
m_sTitle = A_sTitle;
m_sMask = A_sMask;
m_nInputLenght = A_nInputLength;
}

protected string Title
{
get { return m_sTitle; }
set { SetProperty(ref m_sTitle, value, () => Title); }
}
protected string Mask
{
get { return m_sMask; }
set { SetProperty(ref m_sMask, value, () => Mask); }
}

protected int InputLength
{
get { return m_nInputLenght; }
set { SetProperty(ref m_nInputLenght, value, () => InputLength); }
}

protected string Whoami
{
get { return m_sWhoami; }
set { SetProperty(ref m_sWhoami, value, () => Whoami); }
}
}

public class TInputValueVM : TInputBaseVM
{
public TInputValueVM(string A_sTitle, string A_sMask, int A_nInputLength, double A_nValue) : base(A_sTitle, A_sMask, A_nInputLength)
{
Value = A_nValue;
Whoami = "Value";
}

private double m_nValue;
public double Value
{
get { return m_nValue; }
set { SetProperty(ref m_nValue, value, () => Value); }
}
}

public class TInputTextVM : TInputBaseVM
{
public TInputTextVM(string A_sTitle, string A_sMask, int A_nInputLength, string A_sValue) : base(A_sTitle, A_sMask, A_nInputLength)
{
Value = A_sValue;
Whoami = "Text";
}

private string m_sValue;
public string Value
{
get { return m_sValue; }
set { SetProperty(ref m_sValue, value, () => Value); }
}
}

public class PropertyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate DataTemplate_Value { get; set; }
public DataTemplate DataTemplate_Text { get; set; }

public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var selector = item as string;

if(selector == "Value")
return DataTemplate_Value;
return DataTemplate_Text;
}
}

}


In c++/cli I create an object of a proper VM and I'd like the WPF to automatically update the view to either spinedit or textedit, however I'm not sure how to properly bind the properties from the C#. If I explicitly type 'Value' in the Content property of the ContentControl then it displays the spinEdit but I don't know how to bind it so it automatically takes the correct property.



EDIT: I'm adding c++/cli code to show how I choose different VMs



C++/cli:



bool TSignalNumberPositionDialogCLR::StartDialog(TSignalNumberPositionSupport& A_Attributes, HWND A_hwndParent, LPTSTR String)
{
try
{
TInputValueVM ^oExchange_Value;
TInputTextVM ^oExchange_Text;

int inputFormat = A_Attributes.GetInputFormat();

if(inputFormat)
oExchange_Text = gcnew TInputTextVM(gcnew System::String(A_Attributes.GetTitle()), gcnew System::String(A_Attributes.GetMask()),
A_Attributes.GetInputLength(), gcnew System::String(A_Attributes.GetInitialText()));
else
oExchange_Value = gcnew TInputValueVM(gcnew System::String(A_Attributes.GetTitle()), gcnew System::String(A_Attributes.GetMask()),
A_Attributes.GetInputLength(), A_Attributes.GetInitialValue());


Dialogs::TSignalNumberPositionDialog^ dialog = gcnew Dialogs::TSignalNumberPositionDialog();

if(inputFormat)
dialog->DataContext = oExchange_Text;
else
dialog->DataContext = oExchange_Value;

dialog->ShowDialog();

if(dialog->DialogResult)
{
CString nValue;

if(inputFormat)
nValue = oExchange_Text->Value;
else
nValue = ((Decimal)oExchange_Value->Value).ToString("F2", CultureInfo::InvariantCulture);

A_Attributes.UpdateValue(nValue, String, A_Attributes.GetInputLength());
return true;
}

return false;
}
catch(Exception^ e)
{
e;
}
}


based on the 'inputFormat' variable I want to display different controls in the dialog.



EDIT: Based on @Clemens comments I got rid of the selector sectionand the x:Key property in the DataTemplates. I changed the content opf the Content property to Content="{Binding}" and it somehow works. The moment I create a VM it selects the correct one.





This question already has an answer here:




  • How to use DataTemplateSelector with ContentControl to display different controls based on the view-model?

    2 answers








c# wpf c++-cli






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 10:36







bananeeek

















asked Nov 13 '18 at 7:28









bananeeekbananeeek

2317




2317




marked as duplicate by Clemens c#
Users with the  c# badge can single-handedly close c# questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 13 '18 at 11:27


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.






marked as duplicate by Clemens c#
Users with the  c# badge can single-handedly close c# questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 13 '18 at 11:27


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.














  • Content="{Binding Path=Whoami}" and the ContentTemplateSelector don't seem to make sense. When you assign or bind an object to the Content property of a ContentControl, the control automatically select an appropriate ContentTemplate via the DataTemplate's DataType, i.e. one that matches the Content type.
    – Clemens
    Nov 13 '18 at 9:35












  • @Clemens So what would I need to do? delete the whole selector section and bind what exactly in the Content property or ContentControl?
    – bananeeek
    Nov 13 '18 at 9:52










  • As said, the ContentTemplate is automatically selected according to the type of the Content. If you bind Content to an object of type MyClass, the DataTemplate with DataType"{x:Type local:MyClass}" and without a x:Key is chosen.
    – Clemens
    Nov 13 '18 at 10:05












  • @Clemens But I have two VMs and two DataTemplates. If I define one DT as DataType"{x:Type local:TInputValueVM}" and the second DT as DataType"(x:Type local:TInputTextVM}" then what do I bind the ControlContent's Content property to?
    – bananeeek
    Nov 13 '18 at 10:16










  • The appropriate view model, for example a property CurrentVM like Content="{Binding CurrentVM}". CurrentVM returns either a TInputValueVM or a TInputTextVM.
    – Clemens
    Nov 13 '18 at 10:29


















  • Content="{Binding Path=Whoami}" and the ContentTemplateSelector don't seem to make sense. When you assign or bind an object to the Content property of a ContentControl, the control automatically select an appropriate ContentTemplate via the DataTemplate's DataType, i.e. one that matches the Content type.
    – Clemens
    Nov 13 '18 at 9:35












  • @Clemens So what would I need to do? delete the whole selector section and bind what exactly in the Content property or ContentControl?
    – bananeeek
    Nov 13 '18 at 9:52










  • As said, the ContentTemplate is automatically selected according to the type of the Content. If you bind Content to an object of type MyClass, the DataTemplate with DataType"{x:Type local:MyClass}" and without a x:Key is chosen.
    – Clemens
    Nov 13 '18 at 10:05












  • @Clemens But I have two VMs and two DataTemplates. If I define one DT as DataType"{x:Type local:TInputValueVM}" and the second DT as DataType"(x:Type local:TInputTextVM}" then what do I bind the ControlContent's Content property to?
    – bananeeek
    Nov 13 '18 at 10:16










  • The appropriate view model, for example a property CurrentVM like Content="{Binding CurrentVM}". CurrentVM returns either a TInputValueVM or a TInputTextVM.
    – Clemens
    Nov 13 '18 at 10:29
















Content="{Binding Path=Whoami}" and the ContentTemplateSelector don't seem to make sense. When you assign or bind an object to the Content property of a ContentControl, the control automatically select an appropriate ContentTemplate via the DataTemplate's DataType, i.e. one that matches the Content type.
– Clemens
Nov 13 '18 at 9:35






Content="{Binding Path=Whoami}" and the ContentTemplateSelector don't seem to make sense. When you assign or bind an object to the Content property of a ContentControl, the control automatically select an appropriate ContentTemplate via the DataTemplate's DataType, i.e. one that matches the Content type.
– Clemens
Nov 13 '18 at 9:35














@Clemens So what would I need to do? delete the whole selector section and bind what exactly in the Content property or ContentControl?
– bananeeek
Nov 13 '18 at 9:52




@Clemens So what would I need to do? delete the whole selector section and bind what exactly in the Content property or ContentControl?
– bananeeek
Nov 13 '18 at 9:52












As said, the ContentTemplate is automatically selected according to the type of the Content. If you bind Content to an object of type MyClass, the DataTemplate with DataType"{x:Type local:MyClass}" and without a x:Key is chosen.
– Clemens
Nov 13 '18 at 10:05






As said, the ContentTemplate is automatically selected according to the type of the Content. If you bind Content to an object of type MyClass, the DataTemplate with DataType"{x:Type local:MyClass}" and without a x:Key is chosen.
– Clemens
Nov 13 '18 at 10:05














@Clemens But I have two VMs and two DataTemplates. If I define one DT as DataType"{x:Type local:TInputValueVM}" and the second DT as DataType"(x:Type local:TInputTextVM}" then what do I bind the ControlContent's Content property to?
– bananeeek
Nov 13 '18 at 10:16




@Clemens But I have two VMs and two DataTemplates. If I define one DT as DataType"{x:Type local:TInputValueVM}" and the second DT as DataType"(x:Type local:TInputTextVM}" then what do I bind the ControlContent's Content property to?
– bananeeek
Nov 13 '18 at 10:16












The appropriate view model, for example a property CurrentVM like Content="{Binding CurrentVM}". CurrentVM returns either a TInputValueVM or a TInputTextVM.
– Clemens
Nov 13 '18 at 10:29




The appropriate view model, for example a property CurrentVM like Content="{Binding CurrentVM}". CurrentVM returns either a TInputValueVM or a TInputTextVM.
– Clemens
Nov 13 '18 at 10:29












1 Answer
1






active

oldest

votes


















1














Based on your comment. Let me improve my answer. As you are facing issue in VM selection. so plesae concentrate how I assigned VM to datatemplate. Although it is done in very basic way, you can handle it if you you are using MVVM packages.
I have created 2 data template and 2 vms and each vm is bound to datatemplate. To verify, I have a combobox, which will select datatemplate based on selected value.



Here is Sample VM



public class VM : System.ComponentModel.INotifyPropertyChanged
{
private string title;
private SolidColorBrush background;

public string Title { get => title; set { title = value; RaisePropertyChanged(); } }
public SolidColorBrush Background { get => background; set { background = value; RaisePropertyChanged(); } }

public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}

public class VM1: VM
{
public VM1()
{
Title = "This is VM1";
Background = Brushes.Yellow;
}
}

public class VM2: VM
{
public VM2()
{
Title = "This is VM2";
Background = Brushes.Orange;
}
}


Now check for resources



<local:VM1 x:Key="VM1"/>
<local:VM2 x:Key="VM2"/>

<DataTemplate x:Key="DT1">
<Grid DataContext="{StaticResource VM1}">
<TextBlock Text="{Binding Title}" Background="{Binding Background}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DT2">
<Grid DataContext="{StaticResource VM2}">
<TextBlock Text="{Binding Title}" Background="{Binding Background}"/>
</Grid>
</DataTemplate>

<Style TargetType="ContentControl" x:Key="contentStyle">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=cmbo, Path=SelectedValue}" Value="Template1">
<Setter Property="ContentTemplate" Value="{StaticResource DT1}" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=cmbo, Path=SelectedValue}" Value="Template2">
<Setter Property="ContentTemplate" Value="{StaticResource DT2}" />
</DataTrigger>
</Style.Triggers>
</Style>


and finally I have combobox and content control just to verify



    <ComboBox Name="cmbo"/>

<ContentControl Style="{StaticResource contentStyle}"/>


where cmbo.ItemsSource = new List { "Template1", "Template2" };



Hope you got the point






share|improve this answer























  • Do I define that in the xaml? I have added this.DataContext = this; In the code behind right where I initialize the component, but I'm not sure how to make a VM a current one. EDIT: Or do I define that datacontext = viewmodel in the selector?
    – bananeeek
    Nov 13 '18 at 8:37








  • 1




    I improved the answer, please go through
    – Kamran Asim
    Nov 13 '18 at 9:17


















1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Based on your comment. Let me improve my answer. As you are facing issue in VM selection. so plesae concentrate how I assigned VM to datatemplate. Although it is done in very basic way, you can handle it if you you are using MVVM packages.
I have created 2 data template and 2 vms and each vm is bound to datatemplate. To verify, I have a combobox, which will select datatemplate based on selected value.



Here is Sample VM



public class VM : System.ComponentModel.INotifyPropertyChanged
{
private string title;
private SolidColorBrush background;

public string Title { get => title; set { title = value; RaisePropertyChanged(); } }
public SolidColorBrush Background { get => background; set { background = value; RaisePropertyChanged(); } }

public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}

public class VM1: VM
{
public VM1()
{
Title = "This is VM1";
Background = Brushes.Yellow;
}
}

public class VM2: VM
{
public VM2()
{
Title = "This is VM2";
Background = Brushes.Orange;
}
}


Now check for resources



<local:VM1 x:Key="VM1"/>
<local:VM2 x:Key="VM2"/>

<DataTemplate x:Key="DT1">
<Grid DataContext="{StaticResource VM1}">
<TextBlock Text="{Binding Title}" Background="{Binding Background}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DT2">
<Grid DataContext="{StaticResource VM2}">
<TextBlock Text="{Binding Title}" Background="{Binding Background}"/>
</Grid>
</DataTemplate>

<Style TargetType="ContentControl" x:Key="contentStyle">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=cmbo, Path=SelectedValue}" Value="Template1">
<Setter Property="ContentTemplate" Value="{StaticResource DT1}" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=cmbo, Path=SelectedValue}" Value="Template2">
<Setter Property="ContentTemplate" Value="{StaticResource DT2}" />
</DataTrigger>
</Style.Triggers>
</Style>


and finally I have combobox and content control just to verify



    <ComboBox Name="cmbo"/>

<ContentControl Style="{StaticResource contentStyle}"/>


where cmbo.ItemsSource = new List { "Template1", "Template2" };



Hope you got the point






share|improve this answer























  • Do I define that in the xaml? I have added this.DataContext = this; In the code behind right where I initialize the component, but I'm not sure how to make a VM a current one. EDIT: Or do I define that datacontext = viewmodel in the selector?
    – bananeeek
    Nov 13 '18 at 8:37








  • 1




    I improved the answer, please go through
    – Kamran Asim
    Nov 13 '18 at 9:17
















1














Based on your comment. Let me improve my answer. As you are facing issue in VM selection. so plesae concentrate how I assigned VM to datatemplate. Although it is done in very basic way, you can handle it if you you are using MVVM packages.
I have created 2 data template and 2 vms and each vm is bound to datatemplate. To verify, I have a combobox, which will select datatemplate based on selected value.



Here is Sample VM



public class VM : System.ComponentModel.INotifyPropertyChanged
{
private string title;
private SolidColorBrush background;

public string Title { get => title; set { title = value; RaisePropertyChanged(); } }
public SolidColorBrush Background { get => background; set { background = value; RaisePropertyChanged(); } }

public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}

public class VM1: VM
{
public VM1()
{
Title = "This is VM1";
Background = Brushes.Yellow;
}
}

public class VM2: VM
{
public VM2()
{
Title = "This is VM2";
Background = Brushes.Orange;
}
}


Now check for resources



<local:VM1 x:Key="VM1"/>
<local:VM2 x:Key="VM2"/>

<DataTemplate x:Key="DT1">
<Grid DataContext="{StaticResource VM1}">
<TextBlock Text="{Binding Title}" Background="{Binding Background}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DT2">
<Grid DataContext="{StaticResource VM2}">
<TextBlock Text="{Binding Title}" Background="{Binding Background}"/>
</Grid>
</DataTemplate>

<Style TargetType="ContentControl" x:Key="contentStyle">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=cmbo, Path=SelectedValue}" Value="Template1">
<Setter Property="ContentTemplate" Value="{StaticResource DT1}" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=cmbo, Path=SelectedValue}" Value="Template2">
<Setter Property="ContentTemplate" Value="{StaticResource DT2}" />
</DataTrigger>
</Style.Triggers>
</Style>


and finally I have combobox and content control just to verify



    <ComboBox Name="cmbo"/>

<ContentControl Style="{StaticResource contentStyle}"/>


where cmbo.ItemsSource = new List { "Template1", "Template2" };



Hope you got the point






share|improve this answer























  • Do I define that in the xaml? I have added this.DataContext = this; In the code behind right where I initialize the component, but I'm not sure how to make a VM a current one. EDIT: Or do I define that datacontext = viewmodel in the selector?
    – bananeeek
    Nov 13 '18 at 8:37








  • 1




    I improved the answer, please go through
    – Kamran Asim
    Nov 13 '18 at 9:17














1












1








1






Based on your comment. Let me improve my answer. As you are facing issue in VM selection. so plesae concentrate how I assigned VM to datatemplate. Although it is done in very basic way, you can handle it if you you are using MVVM packages.
I have created 2 data template and 2 vms and each vm is bound to datatemplate. To verify, I have a combobox, which will select datatemplate based on selected value.



Here is Sample VM



public class VM : System.ComponentModel.INotifyPropertyChanged
{
private string title;
private SolidColorBrush background;

public string Title { get => title; set { title = value; RaisePropertyChanged(); } }
public SolidColorBrush Background { get => background; set { background = value; RaisePropertyChanged(); } }

public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}

public class VM1: VM
{
public VM1()
{
Title = "This is VM1";
Background = Brushes.Yellow;
}
}

public class VM2: VM
{
public VM2()
{
Title = "This is VM2";
Background = Brushes.Orange;
}
}


Now check for resources



<local:VM1 x:Key="VM1"/>
<local:VM2 x:Key="VM2"/>

<DataTemplate x:Key="DT1">
<Grid DataContext="{StaticResource VM1}">
<TextBlock Text="{Binding Title}" Background="{Binding Background}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DT2">
<Grid DataContext="{StaticResource VM2}">
<TextBlock Text="{Binding Title}" Background="{Binding Background}"/>
</Grid>
</DataTemplate>

<Style TargetType="ContentControl" x:Key="contentStyle">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=cmbo, Path=SelectedValue}" Value="Template1">
<Setter Property="ContentTemplate" Value="{StaticResource DT1}" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=cmbo, Path=SelectedValue}" Value="Template2">
<Setter Property="ContentTemplate" Value="{StaticResource DT2}" />
</DataTrigger>
</Style.Triggers>
</Style>


and finally I have combobox and content control just to verify



    <ComboBox Name="cmbo"/>

<ContentControl Style="{StaticResource contentStyle}"/>


where cmbo.ItemsSource = new List { "Template1", "Template2" };



Hope you got the point






share|improve this answer














Based on your comment. Let me improve my answer. As you are facing issue in VM selection. so plesae concentrate how I assigned VM to datatemplate. Although it is done in very basic way, you can handle it if you you are using MVVM packages.
I have created 2 data template and 2 vms and each vm is bound to datatemplate. To verify, I have a combobox, which will select datatemplate based on selected value.



Here is Sample VM



public class VM : System.ComponentModel.INotifyPropertyChanged
{
private string title;
private SolidColorBrush background;

public string Title { get => title; set { title = value; RaisePropertyChanged(); } }
public SolidColorBrush Background { get => background; set { background = value; RaisePropertyChanged(); } }

public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}

public class VM1: VM
{
public VM1()
{
Title = "This is VM1";
Background = Brushes.Yellow;
}
}

public class VM2: VM
{
public VM2()
{
Title = "This is VM2";
Background = Brushes.Orange;
}
}


Now check for resources



<local:VM1 x:Key="VM1"/>
<local:VM2 x:Key="VM2"/>

<DataTemplate x:Key="DT1">
<Grid DataContext="{StaticResource VM1}">
<TextBlock Text="{Binding Title}" Background="{Binding Background}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DT2">
<Grid DataContext="{StaticResource VM2}">
<TextBlock Text="{Binding Title}" Background="{Binding Background}"/>
</Grid>
</DataTemplate>

<Style TargetType="ContentControl" x:Key="contentStyle">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=cmbo, Path=SelectedValue}" Value="Template1">
<Setter Property="ContentTemplate" Value="{StaticResource DT1}" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=cmbo, Path=SelectedValue}" Value="Template2">
<Setter Property="ContentTemplate" Value="{StaticResource DT2}" />
</DataTrigger>
</Style.Triggers>
</Style>


and finally I have combobox and content control just to verify



    <ComboBox Name="cmbo"/>

<ContentControl Style="{StaticResource contentStyle}"/>


where cmbo.ItemsSource = new List { "Template1", "Template2" };



Hope you got the point







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 13 '18 at 9:16

























answered Nov 13 '18 at 8:23









Kamran AsimKamran Asim

48426




48426












  • Do I define that in the xaml? I have added this.DataContext = this; In the code behind right where I initialize the component, but I'm not sure how to make a VM a current one. EDIT: Or do I define that datacontext = viewmodel in the selector?
    – bananeeek
    Nov 13 '18 at 8:37








  • 1




    I improved the answer, please go through
    – Kamran Asim
    Nov 13 '18 at 9:17


















  • Do I define that in the xaml? I have added this.DataContext = this; In the code behind right where I initialize the component, but I'm not sure how to make a VM a current one. EDIT: Or do I define that datacontext = viewmodel in the selector?
    – bananeeek
    Nov 13 '18 at 8:37








  • 1




    I improved the answer, please go through
    – Kamran Asim
    Nov 13 '18 at 9:17
















Do I define that in the xaml? I have added this.DataContext = this; In the code behind right where I initialize the component, but I'm not sure how to make a VM a current one. EDIT: Or do I define that datacontext = viewmodel in the selector?
– bananeeek
Nov 13 '18 at 8:37






Do I define that in the xaml? I have added this.DataContext = this; In the code behind right where I initialize the component, but I'm not sure how to make a VM a current one. EDIT: Or do I define that datacontext = viewmodel in the selector?
– bananeeek
Nov 13 '18 at 8:37






1




1




I improved the answer, please go through
– Kamran Asim
Nov 13 '18 at 9:17




I improved the answer, please go through
– Kamran Asim
Nov 13 '18 at 9:17



Popular posts from this blog

List item for chat from Array inside array React Native

Thiostrepton

Caerphilly