I am learning to create an MVVM application following this tutorial, and it has this in its entrance view:
what worked in the example
<UserControl.Resources>
<DataTemplate DataType="{x:Type vm:ProductViewModel}">
<vw:ProductView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SingleBrandViewModel}">
<vw:SingleBrandView />
</DataTemplate>
</UserControl.Resources>
so i tried the following in my code
what didn't work in my code
<Page x:Class="MvvmAttempt.FilesView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MvvmAttempt"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="FilesView">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="resources/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
<local:MySizeConverter x:Key="sizeConverter"/>
<DataTemplate DataType="{x:Type local:SingleFileView}"> <--- error here
<local:SingleFileViewModel/> <--- error here
</DataTemplate>
</ResourceDictionary>
</Page.Resources>
... other stuff ...
</Page>
x:Type has an underlining error message: The type 'x:Type' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.
under <local:SingleFileViewModel/> , the error is: The specified value cannot be assigned. The following type was expected: "DependencyObject".
What could be causing the errors? Why did it expect DependencyObject when there isn't anything alike in the example code? Thanks!
Probably your mistake sits here:
<DataTemplate DataType="{x:Type local:SingleFileView}"> <--- error here
<local:SingleFileViewModel/> <--- error here
</DataTemplate>
Note, that you have specified ViewModel as the DataTemplate, and the View as the DataType of DataTemplate. So it seems to me that this should work:
<DataTemplate DataType="{x:Type local:SingleFileViewModel}">
<local:SingleFileView/>
</DataTemplate>
Related
I'm working on a WPF application using C#. So far, I have added a custom font using a ResourceDictionary on my application. When I run the app I can see the font works fine, but on the Design tab of my XAML it always shows the default font. Could I be missing something to set my designer correctly?
App.xaml
<Application x:Class="Bali.Chat.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Bali.Chat"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/Fonts.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Fonts.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<FontFamily x:Key="LatoRegular">pack://application;,,,/Fonts/#Lato Regular</FontFamily>
<FontFamily x:Key="LatoThin">pack://application;,,,/Fonts/#Lato Thin</FontFamily>
</ResourceDictionary>
MainWindow.xaml
<Window x:Class="Bali.Chat.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Bali.Chat"
mc:Ignorable="d"
Icon="Images/Logo/logo-small.png"
WindowStyle="None"
AllowsTransparency="True"
Title="Bali Chat"
Height="250" Width="400">
<StackPanel>
<TextBlock Text="Default Font!" FontSize="40" />
<TextBlock Text="Thin Font" FontSize="40" FontFamily="{StaticResource LatoThin}" />
<TextBlock Text="Regular Font" FontSize="40" FontFamily="{StaticResource LatoRegular}" />
</StackPanel>
</Window>
This is what I get on my designer
And this is what I get if I run the application
I really would like to preview what I'm trying to render without having to start the application or check it on the live preview. The tutorial I am following does show the presenter seeing the proper font in the designer, so I know there are some issues. Thanks in advance.
<Window x:Class="App1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cust="clr-namespace:App1.Customers"
Title="Customers"
Height="525"
Width="525">
<Window.Resources>
<DataTemplate DataType="{x:Type cust:CustomerViewModel}">
<cust:CustomerView />
</DataTemplate>
</Window.Resources>
<Grid x:Name="MainContent">
<ContentControl Content="{Binding CurrentViewModel}" />
</Grid>
</Window>
I've declared the datatemplate above in xaml. Over time there could be 20 viewmodels and views the main window might need to know about. I'd rather pass responsibility for adding the datatemplate(s) to the resource dictionary to somewhere else. How can I achieve the above in c#? Just the bit which adds the datatemplate to the resource dictionary
Goal: Creating an XAML template which I can reuse and load into my main view. Is this possible? If so how? Ive read about the ResourceDictionary and came up with something but im not sure where to continue from there.
This is the XAML with my resource (kept very dumb and simple):
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel x:Key="myUnneccesaryButtonList">
<Button Content="1"></Button>
<Button Content="2"></Button>
<Button Content="3"></Button>
</StackPanel>
</ResourceDictionary>
Here my MainWindow XAML where I want to use the above template and load it:
<Window x:Class="Sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="Sample" WindowState="Maximized">
<StackPanel x:Name="wrapper" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</StackPanel>
</Window>
Edit: Here is my MainWindow but the Window.Resource declaration doesnt work:
<Window x:Class="Sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="Sample" WindowState="Maximized">
<Window.Resources>
<ResourceDictionary Source="MyDictionary.xaml" >
</Window.Resources>
<StackPanel x:Name="wrapper" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</StackPanel>
</Window>
myUnneccesaryButtonList is not a template but an actual StackPanel instance.
If you set its x:Shared attribute to false in the ResourceDictionary:
<StackPanel x:Key="myUnneccesaryButtonList" x:Shared="False">
<Button Content="1"></Button>
<Button Content="2"></Button>
<Button Content="3"></Button>
</StackPanel>
..you could use a ContentControl to display it in the window:
<ContentControl Content="{StaticResource myUnneccesaryButtonList}" />
What you probably want to do is to create a custom StackPanel class that always adds the Buttons though:
public class CustomStackPanel : System.Windows.Controls.StackPanel
{
public CustomStackPanel()
{
Children.Add(new Button() { Content = "1" });
Children.Add(new Button() { Content = "2" });
Children.Add(new Button() { Content = "3" });
}
}
Usage:
<local:CustomStackPanel x:Name="wrapper" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
if you want a XML Template then you should create a template
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DataTemplate x:Key="myUnneccesaryButtonList">
<StackPanel >
<Button Content="1"></Button>
<Button Content="2"></Button>
<Button Content="3"></Button>
</StackPanel>
</DataTemplate>
</ResourceDictionary>
then you could define a control to host it
<ContentControl ContentTemplate="{StaticResource myUnneccesaryButtonList}" />
or
<ItemsControl ItemTemplate="{StaticResource myUnneccesaryButtonList}" />
Remember add the dictionary into the Resources
<Window.Resources>
<ResourceDictionary Source="YourDictionary.xaml" />
</Window.Resources>
or to merge it in
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="YourDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
I am following a beginner tutorial on MVVM Light and UWP. I have a ViewModel with just a string field that is bound to a TextBlock in main view like this:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Name="Title" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24" Text="{Binding Title}" />
</Grid>
The ViewModelLocator is defined like this in App.xaml:
<Application.Resources>
<vm:ViewModelLocator xmlns:vm="using:MvvmLight.UWP.ViewModels" x:Key="Locator" />
</Application.Resources>
and the ViewModelLocator class looks like this:
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<StartPageViewModel>();
}
public StartPageViewModel StartPageInstance
{
get { return ServiceLocator.Current.GetInstance<StartPageViewModel>(); }
}
In the ViewModel I have this in the constructor:
Title = "Hello world!";
Now, in Design Time, the text appears fine in the designer, but when I run the app, I only get a blank page, and I cannot figure out why?
I think, you only declare the Design Time DataContext, you should also declare the Runtime DataContext in the attributes of your View. For this, add the following:
DataContext="{Binding Source={StaticResource Locator}, Path=StartPageInstance}"
After this, you will have something like that:
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:design="using:App1.Design"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
DataContext="{Binding Source={StaticResource Locator}, Path=StartPageInstance}"
d:DataContext="{d:DesignInstance Type=design:DesignStartPageInstance, IsDesignTimeCreatable=True}"
mc:Ignorable="d">
I have project named FSharpProject in whick there is code like this:
module FSharpProject.ViewModel
type A =
member x.a = 1
In other project(typical wpf application writing in C#) which have reference to FSharpProject I have xaml file like this:
<UserControl x:Class="CSharpProjectView"
x:Name="Root"
xmlns:local="clr-namespace:CSharpProjectView"
xmlns:data="clr-namespace:FSharpProject.ViewModel;assembly=FSharpProject"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
...
<DataTemplate x:Key="LogDataTemplate" DataType="{data:A}">
<TextBlock Text="{Binding a}" />
</DataTemplate>
But I get error that data:A type not found.
UPD: It does not work:
<UserControl x:Class="CSharpProjectView"
x:Name="Root"
xmlns:local="clr-namespace:CSharpProjectView"
xmlns:data="clr-namespace:FSharpProject;assembly=FSharpProject"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
...
<DataTemplate x:Key="LogDataTemplate" DataType="{data:ViewModel.A}">
<TextBlock Text="{Binding a}" />
</DataTemplate>
Your DataType should be simply data:A or {x:Type data:A}:
<DataTemplate x:Key="LogDataTemplate" DataType="data:A">