When I inject the mainpage to the App class constructor I am getting StaticResource not found for key But if I don't inject the Mainpage on the App constructor it works.
I have a global resource Theme file which I call on the App.xaml.cs where i declare the static resource:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Themes/LightTheme.xaml" /> <!--Theme file-->
<ResourceDictionary Source="Themes/DarkTheme.xaml" /> <!--Theme file-->
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
This is my App.cs file:
public App(MainPage mainPage)
{
InitializeComponent();
MainPage = mainPage;
}
The following code is in the MainPage.xaml:
<StackLayout BackgroundColor="{StaticResource SecondaryBackroundColor}" Grid.Row="0">
<Image
Source="ic_logo.png"
SemanticProperties.Description="Cute dot net bot waving hi to you!"
HeightRequest="200"
HorizontalOptions="Center" VerticalOptions="CenterAndExpand"/>
</StackLayout>
I have added the MainPage to the mauiprogram.cs class
builder.Services.AddTransient<MainPage>();
I have created a new project to test your code and met the same error. Then I added two break point. One is on the MainPage's construction method and the other is on the App.cs's construction method.
I found that the mainpage's construction method excute before the app.cs' when I used builder.Services.AddTransient<MainPage>();. So the error appeared.
Finally, you can follow up this issue about Can't use App.xaml resources after Dependency Injection .NET MAUI on the github. Or just use the DynamicResource instead of the StaticResource such as:
<StackLayout BackgroundColor="{DynamicResource SecondaryBackroundColor}"
I have tried it. Using the DynamicResource works.
Related
I am building a Maui App for the first time and want to employ Material Design. I normally use MahApps or Material design depending on the project. However, when adding the resource dictionary I get a Uri error
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Presentation"
x:Class="Presentation.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignExtensions;component/Themes/Generic.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignExtensions;component/Themes/MaterialDesignLightTheme.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
The code blows up everytime but if I miss out the last 3 resource dictionaries (those referring to Material Design) I get no issues. I've added Material Design as a NuGet package as well as the extensions. Can anyone see anything daft that I have done???
Thanks
Dotnet MAUI has Material UI for Android as default now. You can include the material ui just by adding using Google.Android.Material line in your Android folder. Refer this forum for detailed steps.
I was going through some code in our product and saw some colleagues using ResourceDictionary.MergedDictionaries in a way I had not seen it used before:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<toolTips:ToolTips />
<styles:ControlStyles />
<icons:IconDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
tooltips:ToolTips and all the other elements in the MergedDictionaries are ResourceDictionaries.
The regular way of using these according to the internet is to use <ResourceDictionary Source="uri to your xaml file"/>.
So is there any practical difference between both?
If this way works why isn't it used more often as it plays well with code completion?
I've used ResourceDicionary this way only once on a big project and it was benefical in my situation.
Suppose that you have ResourceDictionary in MyDictionary.xaml file.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="YourNamespace.MyDictionary">
</ResourceDictionary>
You can add an x:Class attribute to the ResourceDictionary element and specify the fully qualified name of the code-behind class.
Let's create MyDictionary.xaml.cs with class MyDictionary (name can be different from the name of the xaml file).
public partial class MyDictionary
{
public MyDictionary()
{
InitializeComponent();
}
}
A class must be a partial class. The constructor must be added to the class and InitializeComponent method must be called. The InitializeComponent method will be automatically generated for the class if you set the x:Class attribute in MyDictionary.xaml
Now you can reference MyDictionary in MergedDictionaries
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<local:MyDictionary/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
If you add some DataTemplate into MyDictionary.xaml you can create event handlers in code-behind (handlers will be automatically generated by VS)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="YourNamespace.MyDictionary">
<DataTemplate x:Key="MyTemplate">
<Button Click="Button_Click"/>
</DataTemplate>
</ResourceDictionary>
Code-behind:
public partial class MyDictionary
{
public MyDictionary()
{
InitializeComponent();
}
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
// custom logic
// edit another element, etc.
}
}
If the class is inherited from the ResourceDictionary class then other resources can be accessed from the code-behind.
Example of usage of data template defined in MyDictonary:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<local:MyDictionary/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<ContentControl ContentTemplate="{StaticResource MyTemplate}"/>
</Grid>
From my point of view the biggest advantages are that you can encapsulate logic into separated files (it's easy to maintain and add new features in big projects) and avoid referencing ResourceDictionaries by <ResourceDictionary Source="uri to your xaml file"/>.
We have a ResourceDictionary being referenced as follows
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Theming/AppTheme.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
This works great at runtime. However, the Designer in Visual Studio gives an error in views that reference this UserControl:
IOException: Cannot locate resource 'theming/apptheme.xaml'.
Other SO answers have suggested referencing the ResourceDictionary by specifying the assembly name:
<ResourceDictionary Source="pack://application:,,,/MyDomain.MyApp.Wpf;component/Theming/AppTheme.xaml" />
This makes the Designer happy, but our assembly name is different in staging vs. production, so it would be nice if we didn't have to specify the assembly name. My question is: How can we provide a ResourceDictionary Source URI that makes the Designer happy and does not require specifying the assembly name?
If this is not possible, we might make the URI a static value that is different per build configuration using preprocessor directives.
You can define the UI or resources for your app using XAML.
Resources are typically definitions of some object that you expect to use more than once. To refer to a XAML resource later, you specify a key for a resource that acts like its name.
You can reference a resource throughout an app or from any XAML page within it.
You can define your resources using a ResourceDictionary element from the Windows Runtime XAML.
Then, you can reference your resources by using a StaticResource markup extension or ThemeResource markup extension.
Resources don't have to be strings.
they can be any shareable object, such as styles, templates, brushes, and colors. However, controls, shapes, and other FrameworkElements are not shareable, so they can't be declared as reusable resources.
Example:
<Page.Resources>
<x:String x:Key="key1">Hey</x:String>
<x:String x:Key="key2">Nice</x:String>
</Page.Resources>
you can use those resoures by addressing the keys in their proper location i.e.:
<Label Text="{StaticResource key1}" FontSize="Large" VerticalAlignment="Center"/>
Well, In order to make your project more organized you need to make a ResourceDictionary a seperate file and call it like this (ContentPage part is depending on the page):
<ContentPage.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ContentPage.Resources>
// in this example Styles is in the same folder has the page you can make dynamic resource to access it from all areas or make a path in a proper manner like:
xmlns:themes = "clr-namespace:AppName.Themes;assembly=AppName"
How can we provide a ResourceDictionary Source URI that makes the Designer happy and does not require specifying the assembly name?
you make a dynamic one.
like this:
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
x:Class="App.Themes.Theme"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<Color x:Key="PrimaryColor">#ffffff</Color>
<Color x:Key="PrimaryDarkColor">#0f0f0f</Color>
</ResourceDictionary>
and in app.xaml you do this (if Theme is in folder Themes in main project):
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:themes = "clr-namespace:YourProjectName.Themes;assembly=YourProjectName"
x:Class="YourProjectName.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<themes:Theme />
</ResourceDictionary.MergedDictionaries >
</ResourceDictionary>
</Application.Resources>
then you can do stuff like this anywhere:
BackgroundColor="{DynamicResource PrimaryColor}"
Good Luck!
Hello my team and I recently started developing an win10 uwp application. Application will have a lot of views and components so heavy use of styles is expected, so we need to organize our styles through file/folder structure we did this using following structure (unfortunately I cannot embed images yet see the link):
Anyways my Resource.xaml merges all other dictionaries as following:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/Colors.xaml" />
<ResourceDictionary Source="/Resources/Icons.xaml" />
<ResourceDictionary Source="/Resources/Fonts.xaml" />
<ResourceDictionary Source="/Resources/Converters.xaml" />
<ResourceDictionary Source="/Resources/Buttons.xaml" />
<ResourceDictionary Source="/Resources/RadioButton.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
And in my App.xaml I reference this dictionary:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Resources.xaml" />
</ResourceDictionary.MergedDictionaries>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</ResourceDictionary>
</Application.Resources>
Now I managed to find the source of the problem in my RadioButton.xaml I reference a brush defined in Colors.xaml using StaticResource lookup:
<Setter Property="Foreground" Value="{StaticResource TopMenuTextBrush}" />
If I remove this line everything will start but with it I get following exception:
Exception {Windows.UI.Xaml.Markup.XamlParseException: The text associated with this error code could not be found.
Failed to assign to property
'Windows.UI.Xaml.ResourceDictionary.Source' because the type
'Windows.Foundation.String' cannot be assigned to the type
'Windows.Foundation.Uri'. [Line: 28 Position: 37]} System.Exception
{Windows.UI.Xaml.Markup.XamlParseException}
Interesting thing is when I start the app with this line commented and uncomment it visual studio will recognize the brush and apply it correctly, it only breaks on application start.
We used same approach before when developing WPF, so I'm thinking it might have to do with something regarding application deployment.
All help is greatly appreciated.
Exception = {Windows.UI.Xaml.Markup.XamlParseException: The text associated with this error code could not be found.
The problem is that you have used wrong ResourceDictionary source . I found the Resources.xaml and other xaml file stored in the same level directory in your screenshot. So you could not declare the parent directory of these xaml files within source. Please modify ResourceDictionary like the following
<ResourceDictionary Source="Colors.xaml"/>
For more you could refer to ResourceDictionary and XAML resource references.
I have the following problem:
I want to implement MvvM in Best-Practice style so I wanted to implement MvvM like in this Microsoft-Video. The video takes ~ 1 hour, so I compress the content:
In the App.xaml.cs the OnStartup-Event is being overwritten, so that I manually instantiate the MainWindow.
There's a MainViewModel which contains an ObservableCollection<ViewModelBase> property, the MainWindow's ItemsControl is bound to that
This MainViewModel is being instantiated in the App.xaml.cs and the MainWindow's DataContextis set to this.
The MainWindow.xaml contains a DataTemplate which is of type ViewModelBase and contains a MainView
So, I have several Views and ViewModels. But when I place several Views into the MainView, only one View has filled values (every time the View, which is being placed first in the MainView.xaml). I know how it should work:
The Views are all placed in the MainView and that MainView is shown in the MainWindow. Because I set the MainWindow's DataContext to the MainViewModel, the MainWindow's ItemsControl (it's ItemsSource) is successfully bound to the ViewModels collection of the MainViewModel.
But I did never set the DataContext of the particular Views to their corresponding ViewModel. Does Visual Studio automatically bind the corresponding Views and ViewModels due to naming convention?
However, only the View, which is being placed at first in the MainView, has beed filled with values. When I swap the 2nd and the 1. Views places in the XAML-File, the formerly 2nd View works now, but the formerly 1. View doesn't have any values filled in anymore. Why is that so?
Of Course i can add specific code, if you want.
But I did never set the DataContext of the particular Views to their corresponding ViewModel. Does Visual Studio automatically bind the corresponding Views and ViewModels due to naming convention?
Now I know, that the DataTemplate I set replaces each Instance of DataType with an instance of a class I want to be instantiated instead.
So each View will be mapped into the MainView (and then the MainView will be mapped into the MainWindow) by replacing each of the corresponding 'ViewModel'-instance with it's View.
One problem solved, and another one pops up:
I have a few styles declared in my App.xaml in a ResourceDictionary:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Orange.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
And when I add the DataTemplates I need:
<Application.Resources>
<DataTemplate DataType="{x:Type vm:OperationViewModel}" x:Key="OpKey">
<v:OperationView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:PlayerViewModel}" x:Key="PKey">
<v:PlayerView/>
</DataTemplate>
<ResourceDictionary x:Key="MetroStyle">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Orange.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
But then I get kind of a Black-Screen so that the declared style (not the DataTemplate) is not being applied. I really dont have much knowledge about ResourceDictionarys and the App.Xaml, so how can I solve this?