Force ViewModel Instantiation from XAML
I have a View OutputOptionsView
which holds several UserControls
with options settings which are displayed depending on the selection of a combobox.
I create the Datacontext
and Datatemplates
for the UserControls
within OutputOptionsView
like this:
<UserControl.Resources>
<ResourceDictionary>
<local:OutputOptionsViewModel x:Key="vm" />
<DataTemplate x:Key="OptionSettings1" DataType="{x:Type views:OptionSettings1View}">
<views:OptionSettings1View />
</DataTemplate>
<DataTemplate x:Key="OptionSettings2" DataType="{x:Type views:OptionSettings2View}">
<views:OptionSettings2View />
</DataTemplate>
....
</ResourceDictionary>
</UserControl.Resources>
The display of the OptionSettingsViews
is handled as follows:
<ContentControl Name="OutputOptionsContentControl" Content="{Binding}" >
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource OptionSettings1}" />
<Style.Triggers>
<DataTrigger Binding="{Binding AvailableOptionsListSelectedIndex}" Value="1">
<Setter Property="ContentTemplate" Value="{StaticResource OptionSettings2}" />
</DataTrigger>
...
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
ItemsSource
and SelectedIndex
of the ComboBox are bound to the viewmodel class OutputOptionsViewModel
of the OutputOptionsView
:
<ComboBox Name="AvailableOptionsListComboBox" ItemsSource="{Binding AvailableOptionsList}" DisplayMemberPath="OptionTitle"
SelectedIndex="{Binding AvailableOptionsListSelectedIndex, UpdateSourceTrigger=PropertyChanged}"/>
Each of my OptionSettings
view also gets a ViewModel:
<UserControl.Resources>
<ResourceDictionary>
<local:OptionSettings1ViewModel x:Key="vm" />
</ResourceDictionary>
</UserControl.Resources>
<Grid DataContext="{StaticResource vm}">
...
</Grid>
Now my Issue concerns the population of the population of the combobox. I created an Interface containing the OptionTitle which each OptionsSettingsViewModels
inherits. AvailableOptionsList
which is the ItemsSouce
for the combobox is a List of this Interface.
public List<IOutputOption> AvailableOptionsList { get; set; }
It will be instantiated within the Constructor of the OutputOptionsViewModel
class.
Within each of the OptionSettingsViewModel
class constructors I add the respective OptionsSettingsViewModel
to this List:
public OptionSettings1ViewModel()
{
OutputOptionsViewModel.AvailableOptionsList.Add(this);
}
This leads to the following Problem: The combobox isn't populated as long as the OptionSettingsViews aren't instantiated, but they can't be instantiated , because they can't be selected from the empty combobox.
Therefore I'm looking to force the Instantiation of the OptionSettingsViews.
c# wpf mvvm
|
show 11 more comments
I have a View OutputOptionsView
which holds several UserControls
with options settings which are displayed depending on the selection of a combobox.
I create the Datacontext
and Datatemplates
for the UserControls
within OutputOptionsView
like this:
<UserControl.Resources>
<ResourceDictionary>
<local:OutputOptionsViewModel x:Key="vm" />
<DataTemplate x:Key="OptionSettings1" DataType="{x:Type views:OptionSettings1View}">
<views:OptionSettings1View />
</DataTemplate>
<DataTemplate x:Key="OptionSettings2" DataType="{x:Type views:OptionSettings2View}">
<views:OptionSettings2View />
</DataTemplate>
....
</ResourceDictionary>
</UserControl.Resources>
The display of the OptionSettingsViews
is handled as follows:
<ContentControl Name="OutputOptionsContentControl" Content="{Binding}" >
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource OptionSettings1}" />
<Style.Triggers>
<DataTrigger Binding="{Binding AvailableOptionsListSelectedIndex}" Value="1">
<Setter Property="ContentTemplate" Value="{StaticResource OptionSettings2}" />
</DataTrigger>
...
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
ItemsSource
and SelectedIndex
of the ComboBox are bound to the viewmodel class OutputOptionsViewModel
of the OutputOptionsView
:
<ComboBox Name="AvailableOptionsListComboBox" ItemsSource="{Binding AvailableOptionsList}" DisplayMemberPath="OptionTitle"
SelectedIndex="{Binding AvailableOptionsListSelectedIndex, UpdateSourceTrigger=PropertyChanged}"/>
Each of my OptionSettings
view also gets a ViewModel:
<UserControl.Resources>
<ResourceDictionary>
<local:OptionSettings1ViewModel x:Key="vm" />
</ResourceDictionary>
</UserControl.Resources>
<Grid DataContext="{StaticResource vm}">
...
</Grid>
Now my Issue concerns the population of the population of the combobox. I created an Interface containing the OptionTitle which each OptionsSettingsViewModels
inherits. AvailableOptionsList
which is the ItemsSouce
for the combobox is a List of this Interface.
public List<IOutputOption> AvailableOptionsList { get; set; }
It will be instantiated within the Constructor of the OutputOptionsViewModel
class.
Within each of the OptionSettingsViewModel
class constructors I add the respective OptionsSettingsViewModel
to this List:
public OptionSettings1ViewModel()
{
OutputOptionsViewModel.AvailableOptionsList.Add(this);
}
This leads to the following Problem: The combobox isn't populated as long as the OptionSettingsViews aren't instantiated, but they can't be instantiated , because they can't be selected from the empty combobox.
Therefore I'm looking to force the Instantiation of the OptionSettingsViews.
c# wpf mvvm
2
A view model that "holds several UserControls" is poor design in the first place. It should instead hold several child view models, and UserControls should be instantiated by DataTemplates for the child view model types.
– Clemens
Nov 14 '18 at 14:38
@Clemens I meantView
, already edited in the OP, sorry. So eachViewModel
only has one View.
– Roland Deschain
Nov 14 '18 at 14:40
Anyway, if you only set the DataType of a DateTemplate to a certain type, without applying anx:Key
, the DataTemplate will by used automatically when you assign an instance of the type to the Content property of a ContentControl. "View model instantiation from XAML", i.e. from the view is the wrong way round. The view should be created for the view model.
– Clemens
Nov 14 '18 at 14:41
@Clemens I'm sorry, but I don't follow what you mean I should do by that.
– Roland Deschain
Nov 14 '18 at 14:54
1
@grek40 fair enough, I completely started over and wrote the question again. I hope things are explained a bit better now.
– Roland Deschain
Nov 14 '18 at 18:43
|
show 11 more comments
I have a View OutputOptionsView
which holds several UserControls
with options settings which are displayed depending on the selection of a combobox.
I create the Datacontext
and Datatemplates
for the UserControls
within OutputOptionsView
like this:
<UserControl.Resources>
<ResourceDictionary>
<local:OutputOptionsViewModel x:Key="vm" />
<DataTemplate x:Key="OptionSettings1" DataType="{x:Type views:OptionSettings1View}">
<views:OptionSettings1View />
</DataTemplate>
<DataTemplate x:Key="OptionSettings2" DataType="{x:Type views:OptionSettings2View}">
<views:OptionSettings2View />
</DataTemplate>
....
</ResourceDictionary>
</UserControl.Resources>
The display of the OptionSettingsViews
is handled as follows:
<ContentControl Name="OutputOptionsContentControl" Content="{Binding}" >
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource OptionSettings1}" />
<Style.Triggers>
<DataTrigger Binding="{Binding AvailableOptionsListSelectedIndex}" Value="1">
<Setter Property="ContentTemplate" Value="{StaticResource OptionSettings2}" />
</DataTrigger>
...
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
ItemsSource
and SelectedIndex
of the ComboBox are bound to the viewmodel class OutputOptionsViewModel
of the OutputOptionsView
:
<ComboBox Name="AvailableOptionsListComboBox" ItemsSource="{Binding AvailableOptionsList}" DisplayMemberPath="OptionTitle"
SelectedIndex="{Binding AvailableOptionsListSelectedIndex, UpdateSourceTrigger=PropertyChanged}"/>
Each of my OptionSettings
view also gets a ViewModel:
<UserControl.Resources>
<ResourceDictionary>
<local:OptionSettings1ViewModel x:Key="vm" />
</ResourceDictionary>
</UserControl.Resources>
<Grid DataContext="{StaticResource vm}">
...
</Grid>
Now my Issue concerns the population of the population of the combobox. I created an Interface containing the OptionTitle which each OptionsSettingsViewModels
inherits. AvailableOptionsList
which is the ItemsSouce
for the combobox is a List of this Interface.
public List<IOutputOption> AvailableOptionsList { get; set; }
It will be instantiated within the Constructor of the OutputOptionsViewModel
class.
Within each of the OptionSettingsViewModel
class constructors I add the respective OptionsSettingsViewModel
to this List:
public OptionSettings1ViewModel()
{
OutputOptionsViewModel.AvailableOptionsList.Add(this);
}
This leads to the following Problem: The combobox isn't populated as long as the OptionSettingsViews aren't instantiated, but they can't be instantiated , because they can't be selected from the empty combobox.
Therefore I'm looking to force the Instantiation of the OptionSettingsViews.
c# wpf mvvm
I have a View OutputOptionsView
which holds several UserControls
with options settings which are displayed depending on the selection of a combobox.
I create the Datacontext
and Datatemplates
for the UserControls
within OutputOptionsView
like this:
<UserControl.Resources>
<ResourceDictionary>
<local:OutputOptionsViewModel x:Key="vm" />
<DataTemplate x:Key="OptionSettings1" DataType="{x:Type views:OptionSettings1View}">
<views:OptionSettings1View />
</DataTemplate>
<DataTemplate x:Key="OptionSettings2" DataType="{x:Type views:OptionSettings2View}">
<views:OptionSettings2View />
</DataTemplate>
....
</ResourceDictionary>
</UserControl.Resources>
The display of the OptionSettingsViews
is handled as follows:
<ContentControl Name="OutputOptionsContentControl" Content="{Binding}" >
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource OptionSettings1}" />
<Style.Triggers>
<DataTrigger Binding="{Binding AvailableOptionsListSelectedIndex}" Value="1">
<Setter Property="ContentTemplate" Value="{StaticResource OptionSettings2}" />
</DataTrigger>
...
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
ItemsSource
and SelectedIndex
of the ComboBox are bound to the viewmodel class OutputOptionsViewModel
of the OutputOptionsView
:
<ComboBox Name="AvailableOptionsListComboBox" ItemsSource="{Binding AvailableOptionsList}" DisplayMemberPath="OptionTitle"
SelectedIndex="{Binding AvailableOptionsListSelectedIndex, UpdateSourceTrigger=PropertyChanged}"/>
Each of my OptionSettings
view also gets a ViewModel:
<UserControl.Resources>
<ResourceDictionary>
<local:OptionSettings1ViewModel x:Key="vm" />
</ResourceDictionary>
</UserControl.Resources>
<Grid DataContext="{StaticResource vm}">
...
</Grid>
Now my Issue concerns the population of the population of the combobox. I created an Interface containing the OptionTitle which each OptionsSettingsViewModels
inherits. AvailableOptionsList
which is the ItemsSouce
for the combobox is a List of this Interface.
public List<IOutputOption> AvailableOptionsList { get; set; }
It will be instantiated within the Constructor of the OutputOptionsViewModel
class.
Within each of the OptionSettingsViewModel
class constructors I add the respective OptionsSettingsViewModel
to this List:
public OptionSettings1ViewModel()
{
OutputOptionsViewModel.AvailableOptionsList.Add(this);
}
This leads to the following Problem: The combobox isn't populated as long as the OptionSettingsViews aren't instantiated, but they can't be instantiated , because they can't be selected from the empty combobox.
Therefore I'm looking to force the Instantiation of the OptionSettingsViews.
c# wpf mvvm
c# wpf mvvm
edited Nov 14 '18 at 18:48
Roland Deschain
asked Nov 14 '18 at 14:35
Roland DeschainRoland Deschain
16611
16611
2
A view model that "holds several UserControls" is poor design in the first place. It should instead hold several child view models, and UserControls should be instantiated by DataTemplates for the child view model types.
– Clemens
Nov 14 '18 at 14:38
@Clemens I meantView
, already edited in the OP, sorry. So eachViewModel
only has one View.
– Roland Deschain
Nov 14 '18 at 14:40
Anyway, if you only set the DataType of a DateTemplate to a certain type, without applying anx:Key
, the DataTemplate will by used automatically when you assign an instance of the type to the Content property of a ContentControl. "View model instantiation from XAML", i.e. from the view is the wrong way round. The view should be created for the view model.
– Clemens
Nov 14 '18 at 14:41
@Clemens I'm sorry, but I don't follow what you mean I should do by that.
– Roland Deschain
Nov 14 '18 at 14:54
1
@grek40 fair enough, I completely started over and wrote the question again. I hope things are explained a bit better now.
– Roland Deschain
Nov 14 '18 at 18:43
|
show 11 more comments
2
A view model that "holds several UserControls" is poor design in the first place. It should instead hold several child view models, and UserControls should be instantiated by DataTemplates for the child view model types.
– Clemens
Nov 14 '18 at 14:38
@Clemens I meantView
, already edited in the OP, sorry. So eachViewModel
only has one View.
– Roland Deschain
Nov 14 '18 at 14:40
Anyway, if you only set the DataType of a DateTemplate to a certain type, without applying anx:Key
, the DataTemplate will by used automatically when you assign an instance of the type to the Content property of a ContentControl. "View model instantiation from XAML", i.e. from the view is the wrong way round. The view should be created for the view model.
– Clemens
Nov 14 '18 at 14:41
@Clemens I'm sorry, but I don't follow what you mean I should do by that.
– Roland Deschain
Nov 14 '18 at 14:54
1
@grek40 fair enough, I completely started over and wrote the question again. I hope things are explained a bit better now.
– Roland Deschain
Nov 14 '18 at 18:43
2
2
A view model that "holds several UserControls" is poor design in the first place. It should instead hold several child view models, and UserControls should be instantiated by DataTemplates for the child view model types.
– Clemens
Nov 14 '18 at 14:38
A view model that "holds several UserControls" is poor design in the first place. It should instead hold several child view models, and UserControls should be instantiated by DataTemplates for the child view model types.
– Clemens
Nov 14 '18 at 14:38
@Clemens I meant
View
, already edited in the OP, sorry. So each ViewModel
only has one View.– Roland Deschain
Nov 14 '18 at 14:40
@Clemens I meant
View
, already edited in the OP, sorry. So each ViewModel
only has one View.– Roland Deschain
Nov 14 '18 at 14:40
Anyway, if you only set the DataType of a DateTemplate to a certain type, without applying an
x:Key
, the DataTemplate will by used automatically when you assign an instance of the type to the Content property of a ContentControl. "View model instantiation from XAML", i.e. from the view is the wrong way round. The view should be created for the view model.– Clemens
Nov 14 '18 at 14:41
Anyway, if you only set the DataType of a DateTemplate to a certain type, without applying an
x:Key
, the DataTemplate will by used automatically when you assign an instance of the type to the Content property of a ContentControl. "View model instantiation from XAML", i.e. from the view is the wrong way round. The view should be created for the view model.– Clemens
Nov 14 '18 at 14:41
@Clemens I'm sorry, but I don't follow what you mean I should do by that.
– Roland Deschain
Nov 14 '18 at 14:54
@Clemens I'm sorry, but I don't follow what you mean I should do by that.
– Roland Deschain
Nov 14 '18 at 14:54
1
1
@grek40 fair enough, I completely started over and wrote the question again. I hope things are explained a bit better now.
– Roland Deschain
Nov 14 '18 at 18:43
@grek40 fair enough, I completely started over and wrote the question again. I hope things are explained a bit better now.
– Roland Deschain
Nov 14 '18 at 18:43
|
show 11 more comments
1 Answer
1
active
oldest
votes
The comments made me think, there is some basic misunderstanding:
[Lynn Crumbling] I'd completely re-architect this to always instantiate all of the viewmodels, nesting them under the mainviewmodel. You're going to need them, so why not just spin them up in the ctor of the main vm?
and
[Roland Deschain] that is actually how I solved it at the moment, however this means that I have to set the datacontext in the code-behind of each optionssettingsviewmodel, which was what I wanted to avoid if possible
So, as Lynn said, you should start by registering the sub-viewmodels within the main viewmodel, no need for any view involvement at this point.
Then you can define DataTemplate
for the viewmodels, not for the views as you do now.
<DataTemplate DataType="{x:Type viewmodels:OptionSettings1ViewModel}">
<views:OptionSettings1View />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:OptionSettings2ViewModel}">
<views:OptionSettings2View />
</DataTemplate>
By removing the x:Key
and changing the DataType
to the viewmodel type, the templates will be automatically selected to display content of the respective type.
The DataContext of your sub-views will be automatically set from the outside. Do not instantiate a sub-viewmodel within the controls xaml.
In your main OutputOptionsViewModel
, you should host a collection of the sub-viewmodels. In your combobox, you should directly use this collection as itemssource.
Then just drop all the complicated template selection xaml and directly bind the content to your selected sub-viewmodel:
<ContentControl
Name="OutputOptionsContentControl"
Content="{Binding ElementName=AvailableOptionsListComboBox,Path=SelectedItem}" />
Thx, I will test this out in the next days!
– Roland Deschain
Nov 15 '18 at 7:32
Just tested this out and it works like a charm. Thanks a lot!
– Roland Deschain
Nov 19 '18 at 10:39
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53302649%2fforce-viewmodel-instantiation-from-xaml%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The comments made me think, there is some basic misunderstanding:
[Lynn Crumbling] I'd completely re-architect this to always instantiate all of the viewmodels, nesting them under the mainviewmodel. You're going to need them, so why not just spin them up in the ctor of the main vm?
and
[Roland Deschain] that is actually how I solved it at the moment, however this means that I have to set the datacontext in the code-behind of each optionssettingsviewmodel, which was what I wanted to avoid if possible
So, as Lynn said, you should start by registering the sub-viewmodels within the main viewmodel, no need for any view involvement at this point.
Then you can define DataTemplate
for the viewmodels, not for the views as you do now.
<DataTemplate DataType="{x:Type viewmodels:OptionSettings1ViewModel}">
<views:OptionSettings1View />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:OptionSettings2ViewModel}">
<views:OptionSettings2View />
</DataTemplate>
By removing the x:Key
and changing the DataType
to the viewmodel type, the templates will be automatically selected to display content of the respective type.
The DataContext of your sub-views will be automatically set from the outside. Do not instantiate a sub-viewmodel within the controls xaml.
In your main OutputOptionsViewModel
, you should host a collection of the sub-viewmodels. In your combobox, you should directly use this collection as itemssource.
Then just drop all the complicated template selection xaml and directly bind the content to your selected sub-viewmodel:
<ContentControl
Name="OutputOptionsContentControl"
Content="{Binding ElementName=AvailableOptionsListComboBox,Path=SelectedItem}" />
Thx, I will test this out in the next days!
– Roland Deschain
Nov 15 '18 at 7:32
Just tested this out and it works like a charm. Thanks a lot!
– Roland Deschain
Nov 19 '18 at 10:39
add a comment |
The comments made me think, there is some basic misunderstanding:
[Lynn Crumbling] I'd completely re-architect this to always instantiate all of the viewmodels, nesting them under the mainviewmodel. You're going to need them, so why not just spin them up in the ctor of the main vm?
and
[Roland Deschain] that is actually how I solved it at the moment, however this means that I have to set the datacontext in the code-behind of each optionssettingsviewmodel, which was what I wanted to avoid if possible
So, as Lynn said, you should start by registering the sub-viewmodels within the main viewmodel, no need for any view involvement at this point.
Then you can define DataTemplate
for the viewmodels, not for the views as you do now.
<DataTemplate DataType="{x:Type viewmodels:OptionSettings1ViewModel}">
<views:OptionSettings1View />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:OptionSettings2ViewModel}">
<views:OptionSettings2View />
</DataTemplate>
By removing the x:Key
and changing the DataType
to the viewmodel type, the templates will be automatically selected to display content of the respective type.
The DataContext of your sub-views will be automatically set from the outside. Do not instantiate a sub-viewmodel within the controls xaml.
In your main OutputOptionsViewModel
, you should host a collection of the sub-viewmodels. In your combobox, you should directly use this collection as itemssource.
Then just drop all the complicated template selection xaml and directly bind the content to your selected sub-viewmodel:
<ContentControl
Name="OutputOptionsContentControl"
Content="{Binding ElementName=AvailableOptionsListComboBox,Path=SelectedItem}" />
Thx, I will test this out in the next days!
– Roland Deschain
Nov 15 '18 at 7:32
Just tested this out and it works like a charm. Thanks a lot!
– Roland Deschain
Nov 19 '18 at 10:39
add a comment |
The comments made me think, there is some basic misunderstanding:
[Lynn Crumbling] I'd completely re-architect this to always instantiate all of the viewmodels, nesting them under the mainviewmodel. You're going to need them, so why not just spin them up in the ctor of the main vm?
and
[Roland Deschain] that is actually how I solved it at the moment, however this means that I have to set the datacontext in the code-behind of each optionssettingsviewmodel, which was what I wanted to avoid if possible
So, as Lynn said, you should start by registering the sub-viewmodels within the main viewmodel, no need for any view involvement at this point.
Then you can define DataTemplate
for the viewmodels, not for the views as you do now.
<DataTemplate DataType="{x:Type viewmodels:OptionSettings1ViewModel}">
<views:OptionSettings1View />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:OptionSettings2ViewModel}">
<views:OptionSettings2View />
</DataTemplate>
By removing the x:Key
and changing the DataType
to the viewmodel type, the templates will be automatically selected to display content of the respective type.
The DataContext of your sub-views will be automatically set from the outside. Do not instantiate a sub-viewmodel within the controls xaml.
In your main OutputOptionsViewModel
, you should host a collection of the sub-viewmodels. In your combobox, you should directly use this collection as itemssource.
Then just drop all the complicated template selection xaml and directly bind the content to your selected sub-viewmodel:
<ContentControl
Name="OutputOptionsContentControl"
Content="{Binding ElementName=AvailableOptionsListComboBox,Path=SelectedItem}" />
The comments made me think, there is some basic misunderstanding:
[Lynn Crumbling] I'd completely re-architect this to always instantiate all of the viewmodels, nesting them under the mainviewmodel. You're going to need them, so why not just spin them up in the ctor of the main vm?
and
[Roland Deschain] that is actually how I solved it at the moment, however this means that I have to set the datacontext in the code-behind of each optionssettingsviewmodel, which was what I wanted to avoid if possible
So, as Lynn said, you should start by registering the sub-viewmodels within the main viewmodel, no need for any view involvement at this point.
Then you can define DataTemplate
for the viewmodels, not for the views as you do now.
<DataTemplate DataType="{x:Type viewmodels:OptionSettings1ViewModel}">
<views:OptionSettings1View />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:OptionSettings2ViewModel}">
<views:OptionSettings2View />
</DataTemplate>
By removing the x:Key
and changing the DataType
to the viewmodel type, the templates will be automatically selected to display content of the respective type.
The DataContext of your sub-views will be automatically set from the outside. Do not instantiate a sub-viewmodel within the controls xaml.
In your main OutputOptionsViewModel
, you should host a collection of the sub-viewmodels. In your combobox, you should directly use this collection as itemssource.
Then just drop all the complicated template selection xaml and directly bind the content to your selected sub-viewmodel:
<ContentControl
Name="OutputOptionsContentControl"
Content="{Binding ElementName=AvailableOptionsListComboBox,Path=SelectedItem}" />
answered Nov 15 '18 at 6:19
grek40grek40
10.3k11135
10.3k11135
Thx, I will test this out in the next days!
– Roland Deschain
Nov 15 '18 at 7:32
Just tested this out and it works like a charm. Thanks a lot!
– Roland Deschain
Nov 19 '18 at 10:39
add a comment |
Thx, I will test this out in the next days!
– Roland Deschain
Nov 15 '18 at 7:32
Just tested this out and it works like a charm. Thanks a lot!
– Roland Deschain
Nov 19 '18 at 10:39
Thx, I will test this out in the next days!
– Roland Deschain
Nov 15 '18 at 7:32
Thx, I will test this out in the next days!
– Roland Deschain
Nov 15 '18 at 7:32
Just tested this out and it works like a charm. Thanks a lot!
– Roland Deschain
Nov 19 '18 at 10:39
Just tested this out and it works like a charm. Thanks a lot!
– Roland Deschain
Nov 19 '18 at 10:39
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53302649%2fforce-viewmodel-instantiation-from-xaml%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
A view model that "holds several UserControls" is poor design in the first place. It should instead hold several child view models, and UserControls should be instantiated by DataTemplates for the child view model types.
– Clemens
Nov 14 '18 at 14:38
@Clemens I meant
View
, already edited in the OP, sorry. So eachViewModel
only has one View.– Roland Deschain
Nov 14 '18 at 14:40
Anyway, if you only set the DataType of a DateTemplate to a certain type, without applying an
x:Key
, the DataTemplate will by used automatically when you assign an instance of the type to the Content property of a ContentControl. "View model instantiation from XAML", i.e. from the view is the wrong way round. The view should be created for the view model.– Clemens
Nov 14 '18 at 14:41
@Clemens I'm sorry, but I don't follow what you mean I should do by that.
– Roland Deschain
Nov 14 '18 at 14:54
1
@grek40 fair enough, I completely started over and wrote the question again. I hope things are explained a bit better now.
– Roland Deschain
Nov 14 '18 at 18:43