MAUI; cannot access colors from resources in code - maui

I am trying to access colors from my colors file (under styles) in my maui application:
<Color x:Key="LiteGreen">#7DD2CD</Color>
<Color x:Key="VeryLiteGreen">#a4dbda</Color>
<Color x:Key="LiteBlue">#c3e1ed</Color>
If I wanna access the colors in xaml, this is how I did it and what worked for me:
BorderColor="{StaticResource LiteGreen}"
Now I tried to access the same color in code:
var color = this.Resources["LiteGreen"] as Color;
Which failes with "LiteGreen is not inside the resource dict"
I tried many different variations but to no avail.
EDIT:
my app.xaml (basic).
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Skillbased"
x:Class="Skillbased.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

You can try the following code:
if (App.Current.Resources.TryGetValue("LiteGreen", out var colorvalue))
   var greencolor = (Color)colorvalue;

When you are adding a Resource to your Application Level i.e. App.xaml.cs then to retrieve it you need to query the application resource not the local resource(all classes that inherit from ContentPage have their own resource).
Try something like:
var liteGreen = Application.Current.Resources["LiteGreen"] as Color;

Related

How to pass objects to PopupPage using MAUI.Toolkit or Mopup plugins?

I have a Maui app where I use MVVM pattern with MAUI Toolkik and also trying with Mopup plugin but I haven't found how to pass objects to Popup pages combined with MVVM. At the moment, I have a page, which I use to navigate to the PopupPage successfully and also I am able to connect the PopupPage with its viewmodel. What I am unable to do is to pass any kind of object to the PopupPage.
I have tried to set the PopupPage constructor with parameters but the methods to navigate to the PopupPage only recognize parameters setted on the code behind.
Here is my code:
Popup
<mopup:PopupPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="NewScholarApp.Views.MessagePopup"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:mopup="clr-namespace:Mopups.Pages;assembly=Mopups"
xmlns:viewmodels="clr-namespace:NewScholarApp.ViewModels"
x:DataType="viewmodels:MessagePopupViewModel">
<mopup:PopupPage.BindingContext>
<viewmodels:MessagePopupViewModel/>
</mopup:PopupPage.BindingContext>
<VerticalStackLayout BackgroundColor="White" HorizontalOptions="Center" VerticalOptions="Center" HeightRequest="100" WidthRequest="100">
<Label
Text="{Binding Message}"
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</mopup:PopupPage>
I use this to navigate from my page viewmodel
await _popupNavigation.PushAsync(new MessagePopup(string text = "tex"));
If I try to set a parameter, shows this error, even that in my PopupPage constructor I have setted a parameter
"MessagePopup does not contain a a constructor that contains 1 argument"
**MessagePopupViewModel **
public partial class MessagePopupViewModel : ObservableObject
{
#region AnP
[ObservableProperty]
private string message;
private readonly IApiService _apiService;
#endregion
public MessagePopupViewModel(string tex)
{
Message = tex;
}
}
you are navigating using this code
await _popupNavigation.PushAsync(new MessagePopup(string text = "tex"));
so MessagePopup MUST have a constructor that accepts a parameter
public MessagePopup(string somevalue)
if you also want to pass that value to your VM, then you can add
BindingContext = new MessagePopupViewModel(somevalue);
if you do this, then you should remove the BindingContext property from the XAML

How to make a multi-steps registration page with multi ContentView?

In the app I'm working on, there's a multi-steps registration, 4 steps:
to accomplish it, I'm thinking to have a single page to host a content view of the registration step, when it passes the validation requirements I remove it and inject the next content view.
This is an example to simplify my need:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamApp"
x:Class="XamApp.MainPage">
<local:Register1/>
</ContentPage>
and the Register1 looks like this:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamApp"
x:Class="XamApp.Register1">
<ContentView.Resources>
<ResourceDictionary>
<local:IntToBoolConverter x:Key="intToBool"/>
</ResourceDictionary>
</ContentView.Resources>
<ContentView.Content>
<StackLayout>
<Label Text="Page 1" FontSize="Large"/>
<Entry x:Name="txtName" Placeholder="Name"/>
<Button Text="Next" IsEnabled="{Binding Source={x:Reference txtName},
Path=Text.Length,
Converter={StaticResource intToBool}}"
Clicked="Button_Clicked"/>
</StackLayout>
</ContentView.Content>
</ContentView>
There are two problems:
1- I don't know how to handle the data (view model) between steps, to have only one object through all steps (Shall I use DI? if yes , then how in MVVMLight?)
2- How to to inject the content view into the main registration page dynamically in an MVVM fashion?
The solution I came up with, is creating an interface:
public interface INavigate
{
INavigate Next();
INavigate Previous();
}
all the ContentViews inherit from, for example the second ContentView implementation:
public INavigate Next()
=> new View3();
public INavigate Previous()
=> new View1();
the container page's Content property is bound to the view model's property CurrentView of type INavigate,
the command of the next button execute this:
CurrentView = CurrentView.Next();
and this is for the previous button:
CurrentView = CurrentView.Previous();

Adding animation in Syncfusion UWP

I am using Syncfusion in UWP app to create a line chart. And I am trying to add animation such that the line extends when we add new data to the collection. Didn't find any help on documentation. The default animation draws between every two data points in it. no other animation was present. Any help is appreciated
Currently We don’t have inbuilt support for animation when the new data point is added to the series dynamically. However, we can achieved your requirement by using CustomTemplate to the LineSeries and the storyboard has been defined in that template for animation. Please find the below code sample for reference,
MainWindow.xaml:
<chart:LineSeries ItemsSource="{Binding Collection}"
XBindingPath="XValue" YBindingPath="YValue"
>
<chart:LineSeries.CustomTemplate>
<DataTemplate>
<Canvas >
<Line X1="{Binding X1}" Y1="{Binding Y1}" X2="{Binding X2}" Y2="{Binding Y2}" Loaded="Line_Loaded" Stroke="{Binding Interior}" Name="line">
<Line.Resources>
<Storyboard x:Name="story" >
<DoubleAnimation x:Name="Danimation1" EnableDependentAnimation="True" Storyboard.TargetName="line" Storyboard.TargetProperty="X2" From="{Binding X1}" To="{Binding X2 }" />
<DoubleAnimation x:Name="Danimation2" EnableDependentAnimation="True" Storyboard.TargetName="line" Storyboard.TargetProperty="Y2" From="{Binding Y1}" To="{Binding Y2}" />
</Storyboard>
</Line.Resources>
</Line>
</Canvas>
</DataTemplate>
</chart:LineSeries.CustomTemplate>
</chart:LineSeries>
MainWindow.cs:
private void Line_Loaded(object sender, RoutedEventArgs e)
{
var line = sender as Line;
Storyboard sb = line.Resources["story"] as Storyboard;
sb.Begin();
}
We have prepared a demo sample based on your requirement and it can be downloaded from the below link,
Sample: Sample
Regards,
Durgadevi S

javafx how to reuse custom component in different FXML

After several searching i could find any solution for this and would like to ask for help. Thanks in advance.
I have a FXML with HBox with several buttons (new, show, edit). Each button has onAction method. It is used in other 2 FXML (A & B) and I would like to reuse such HBox.
Other 2 FXML (A, B) have some controls (tableview, ...)
This is what i tried:
1) import HBox FXML is not an option as changes must be performed in all FXML (a & b).
2) include using fx:id: I will have a dedicated controller for HBox and I would like to have controls and methods on A, B controllers.
3) include using fx:root: I think this is the way to achieve this but i have errors.
Navigation.fxml file:
<fx:root spacing="5.0" type="HBox" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button fx:id="btnOpen" mnemonicParsing="false" onAction="#onActionOpen" text="Open" />
<Button fx:id="btnSave" layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#onActionSave" text="Save" />
<Separator visible="false" HBox.hgrow="ALWAYS" />
<Button fx:id="btnClose" layoutX="62.0" layoutY="10.0" mnemonicParsing="false" onAction="#onActionClose" text="Close" />
</children>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
</fx:root>
Pane1controller.java:
public Pane1Controller() {
System.out.println("Pane1_Controller");
NavigationController nav = new NavigationController();
System.out.println("NavigationController ... done");
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("pane1.fxml"));
System.out.println("setting root");
fxmlLoader.setRoot(this);
System.out.println("setting controller");
fxmlLoader.setController(this);
try {
System.out.println("loading fxml");
pnlMain = fxmlLoader.load();
System.out.println("done");
} catch (IOException exception) {
System.out.println("exception");
pnlMain = null;
throw new RuntimeException(exception);
}
System.out.println("done");
} ...
}
using setRoot ....
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: Root
value already specified.
file:/C:/Users/ecejdap/data/DEV/dev.java.nb/Testfx_fxroot/dist/run573616745/Testfx_fxroot.jar!/testfx_fxroot/pane1.fxml
removing setroot
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: Root value already specified.
file:/C:/Users/ecejdap/data/DEV/dev.java.nb/Testfx_fxroot/dist/run2127482879/Testfx_fxroot.jar!/testfx_fxroot/Navigation.fxml
Which is the correct way to achieve this?
Thanks for your support.
BR
This must be caused due to the <fx:root> tag
I've created a sample project for the above task. Visit GitHub for the project. Clone it and refer. I think you can understand it. Link

How to set different localized string in different visual states in WP7 using Blend?

How do I set different localized strings in different visual states in WP7 using Blend without any code behind?
I can set different non-localized strings in different visual states (although it flickers). That works, but how about localized strings?
If I change the string using data binding in Blend, Blend just overrides the data binding in Base state and not the actual state where I'm recording.
EDIT:
This is how I localize my strings:
I have a resources file named AppPresources.resx. Then I would do this in code:
// setting localized button title
mainButton.Content = AppResources.MainButtonText;
Then I have a GlobalViewModelLocator from MVVM Light Toolkit with the following Property for Databinding.
private static AppResources _localizedStrings;
public AppResources LocalizedStrings
{
get
{
if (_localizedStrings == null)
{
_localizedStrings = new AppResources();
}
return _localizedStrings;
}
}
And in xaml file:
<Button x:Name="mainButton" Content="{Binding LocalizedStrings.MainButtonText, Mode=OneWay, Source={StaticResource Locator}}" ... />
What you need to do, is very close to what you're already doing. First, define a class named Resources.cs with following content
public class Resources
{
private static AppResources resources = new AppResources();
public AppResources LocalizedStrings
{
get
{
return resources;
}
}
}
This allows us to create a instance of your Resource File in XAML. To do this, open App.xaml and add following
<Application.Resources>
<local:Resources x:Key="Resources" />
</Application.Resources>
Now when you need to do bindings in your XAML, you do it like this:
<Button Content="{Binding LocalizedStrings.MainButtonText,
Source={StaticResource Resources}}" />
What you'll notice is that it doesn't work in Blend, yet. To make it work in Expression Blend,
add the following file: DesignTimeResources.xaml in the Properties Folder, and add following content
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:YourNameSpace">
<local:Resources x:Key="Resources" />
</ResourceDictionary>
Now, you press F6 in Visual Studio to recompile, and voila, your localized strings are available in Expression Blend!
A real-world example from one of my projects:
AppResources.cs
DesignTimeResources.xaml
App.xaml