Reputation: 4766
What is the purpose of Application.Resources if my windows cannot access the resources defined within it?
This works, I get a window with a TextBox that says "Loki" inside of it...
App.xaml.cs:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
ViewModel.ViewModel1 oVM = new ViewModel.ViewModel1 { Name = "Loki" };
MainWindow oVW = new MainWindow { Content = oVM };
oVW.ShowDialog();
}
}
MainWindow.xaml
<Window x:Class="TableGenerator.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:TableGenerator.ViewModel"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate DataType="{x:Type vm:ViewModel1}">
<TextBox Text="{Binding Path=Name}" />
</DataTemplate>
</Window.Resources>
<ContentPresenter />
</Window>
But moving the DataTemplate to Application.Resources instead of Window.Resources does not work. When I run this I get a window, there is no TextBox at all, but there is text being displayed somehow that just says the name of my viewmodel class, "TableGenerator.ViewModel.ViewModel1".
App.xaml.cs is unchanged.
MainWindow.xaml changes to:
<Window x:Class="TableGenerator.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<ContentPresenter />
</Window>
App.xaml:
<Application x:Class="TableGenerator.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:TableGenerator.ViewModel">
<Application.Resources>
<DataTemplate DataType="{x:Type vm:ViewModel1}">
<TextBox Text="{Binding Path=Name}" />
</DataTemplate>
</Application.Resources>
</Application>
Why does it not look in Application.Resources to find my DataTemplate?
Upvotes: 3
Views: 7661
Reputation: 5366
Add your datatemplate to a dictionary. It is required to have a default style which application resources should have it seems. Refer link for more explaination. datatemplate in app.xaml is not getting picked up without any styles?
On the creation of every object in XAML, if a default style is present (i.e. style w/ a key of Type) that style should be applied. As you can imagine there are several performance optimizations to make that (implied) lookup a light weight as possible.
One of them is that we don’t look inside Resource Dictionaries unless they are flagged as “containing default Styles”. There is a bug: if all your default styles are nested in merged dictionaries three levels deep (or deeper) the top dictionary does not get flagged so the search skips it. The work around is to put a default Style to something, anything, in the root Dictionary.
Then refer the below code.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:SQ15Mar2015_Learning">
<DataTemplate DataType="{x:Type vm:ViewModel}">
<DockPanel>
<TextBox Text="{Binding Path=Name,UpdateSourceTrigger=PropertyChanged}">
</TextBox>
</DockPanel>
</DataTemplate>
<Application x:Class="SQ15Mar2015_Learning.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:SQ15Mar2015_Learning">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
OR
<Application.Resources>
<DataTemplate DataType="{x:Type vm:ViewModel}">
<DockPanel>
<TextBox Text="{Binding Path=Name,UpdateSourceTrigger=PropertyChanged}">
</TextBox>
</DockPanel>
</DataTemplate>
<Style TargetType="{x:Type Rectangle}" />
</Application.Resources>
class ViewModel : INotifyPropertyChanged
{
private string myVar;
public string Name
{
get { return myVar; }
set
{
if (value != myVar)
{
myVar = value;
OnPropertyChanged("Name");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
ViewModel oVM = new ViewModel { Name = "Loki" };
MainWindow oVW = new MainWindow();
oVW.DataContext = oVM;
oVW.ShowDialog();
}
}
<Window x:Class="SQ15Mar2015_Learning.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:SQ15Mar2015_Learning"
Title="MainWindow" Height="350" Width="525" >
<Grid>
<ContentControl Content="{Binding }" />
</Grid>
</Window>
Upvotes: 8