How to create reusable Components in .NET MAUI? - components

I have just recently started using .Net MAUI. But now I'm wondering how to use a piece of code, e.g. a self-made navigation bar on all my pages, because it doesn't make sense to write the same code on all 10 pages. I like to know if there is a way to create a component that can be reused like in React or Angular?
PS: This question is not specific to a navigation bar but to the general reuse of code in .NET MAUI.
I have so far watched various videos & articles on this topic, however, it is more about custom controls and did not help me. Most articles corresponded to what was conveyed in this video. I also came across this article, but it didn't help me either.
Thanks for your help :)

First, you can create a new .xaml file named Name.xaml. You can write some codes in it.
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CusComponents.Name">
<ContentView.Content>
<StackLayout Padding="10">
<Label Text="Name" FontAttributes="Bold" />
<Label Text="First name" />
<Entry x:Name="FirstName" Placeholder="First name" />
<Label Text="Last name" />
<Entry x:Name="LastName" Placeholder="Last name" />
</StackLayout>
</ContentView.Content>
</ContentView>
Second, you can use it in the page you want like this. You need to add an xmlns reference to the top of the XML file– this is like a using statement in a C# file. Using the namespace structure for the sample project, this will be xmlns:custom_components="clr-namespace:CusComponents".
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:custom_components="clr-namespace:CusComponents"
x:Class="CusComponents.MainPage">
<custom_components:Name />
</ContentPage>
Here is the view of the code:

Related

Shopware6: Plugin configuration is missing

I'm writing my first Shopware 6 plugin and following this howto
But the navigation entry for Plugins will not show up. (URL: admin#/sw/settings/index) and the menu looks like this:
but it should look like this:
My plugin is active (checked in backend), the tables were created, so I guess it is loaded.
I copied the config.xml file from the tutorial into my plugin and validated it (just to be sure).
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/shopware/platform/master/src/Core/System/SystemConfig/Schema/config.xsd">
<card>
<title>Basic Configuration</title>
<title lang="de-DE">Grundeinstellungen</title>
<input-field>
<name>email</name>
<copyable>true</copyable>
<label>eMail address</label>
<label lang="de-DE">E-Mailadresse</label>
<placeholder>you#example.com</placeholder>
<placeholder lang="de-DE">du#beispiel.de</placeholder>
<helpText>Please fill in your personal eMail address</helpText>
<helpText lang="de-DE">Bitte trage deine persönliche E-Mailadresse ein</helpText>
</input-field>
<input-field type="single-select">
<name>mailMethod</name>
<options>
<option>
<id>smtp</id>
<name>English smtp</name>
<name lang="de-DE">German smtp</name>
</option>
<option>
<id>pop3</id>
<name>English pop3</name>
<name lang="de-DE">German pop3</name>
</option>
</options>
<defaultValue>smtp</defaultValue>
<label>Mail method</label>
<label lang="de-DE">Versand-Protokoll</label>
</input-field>
</card>
<card>
<title>Advanced Configuration</title>
<title lang="de-DE">Erweiterte Einstellungen</title>
<input-field type="password">
<name>secret</name>
<label>Secret token</label>
<label lang="de-DE">Geheimschlüssel</label>
<helpText>Your secret token for xyz...</helpText>
<helpText lang="de-DE">Dein geheimer Schlüssel für xyz...</helpText>
</input-field>
</card>
So what is the precondition to show the Plugin navigation entry?
Ok, the problem is, I'm looking at the wrong place.
for the settings tab, you will need an own module with an settingItem
-- Shyim
If one is using a config.xml as I do, you can configure it within the plugin configuration hidden behind the three dots.

Xamarin.Forms styles causing WeakReference leak

I've been spending a lot of time trying to track down memory leaks in our Xamarin.Forms app on Android. After a lot of blind alleys and false dawns, I think I may have come across something which is causing the problem.
Using Xamarin Profiler, I can see that as soon as I create a Style and apply it to a control (or in fact just an implicit style), we get Multiple WeakReferences remaining 'Live' - i.e. not garbage collected.
Note that I assume that the objects to which they refer have been GC'd (because the reference to the object is weak), but the WeakReferences themselves are remaining.
Now of course WeakReferences are small I know - but when you have hundreds created on every iteration of a page push/pop, then the memory adds up and we have a significant leak.
Here are the details.
Using Xamarin.Forms 2.3.4.270 (we haven't upgraded because we want to keep with known issues!)
Running on Android - physical device.
App.xaml:
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:ProfiledFormsApp2;assembly=ProfiledFormsApp2"
x:Class="ProfiledFormsApp2.App">
<Application.Resources>
<ResourceDictionary>
<Style TargetType="Label">
<Setter Property="FontSize" Value="Large" />
<Setter Property="TextColor" Value="Blue" />
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
Page XAML:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage Title="Plain Page" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="ProfiledFormsApp2.PlainPage">
<ContentPage.Content>
<StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="Core Navigation"/>
<Label Text="Number of items:" />
<Label Text="{Binding ItemsCount}" />
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
When I navigate to the above page and back 3 times, we have the following WeakReference (and related) classes created - the screenshot below is from a Profiler snapshot.
Note we have 55 WeakReferences. Drilling into these shows:
What is interesting is that these WeakReferences seem to be created as part of Behavior and Trigger attaching. Looking at the call tree for the top one gives:
So it appears that the WeakReference was created as part of setting a BindableObject's value and the subsequent setting of the Style.
And it also appears that the WeakReference is still in memory and being referenced by something - the Behavior collection?
Using Profiler, I'm can see that we don't have Labels remaining un GC'd. It seems to be something in the Theme/Behavior/Trigger processing.
I haven't looked at the Xamarin.Forms code on GitHub yet - that might have to be my next action.
Has anyone observed this or got a solution?
I am not sure about the implicit styles to the controls but for the explicit styles you can remove them while page is out of scope OR disappearing.
Example, we applied an explicit style to button
<Button x:Name="btnSave" Style="{StaticResource SaveButtonStyle}" Content="Save"/>
protected override void OnDisappearing()
{
btnSave.Style = null;
base.OnDisappearing();
}
Same can be done with Triggers and Behaviors as well (You can clear them).
I think for the implicit styles, there is something within the code of framework only. We can not identify how default style of control is attached with control as default.

Sharepoint hosted app localize to list columns

I created a SharePoint hosted app and a new list. But I want to show its list column display name by a resources file. For that I created a new resource
from rigth click Feature > Add Feature Resource then the created key is PersonName and the value Person Name.
After I wrote in the list schema.xml
<Field ID="{27912FBB-5063-4FF7-9829-B194DDBC7FEB}" Type="Text" Name="PersonName" DisplayName="$Resources:PersonName" Required="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="PersonName" MaxLength="255" />
But the list columns seems to be
$Resources:_FeatureId{54A6CD41-6DB3-45FF-9A2F-D496A13A871F},PersonName;
How can I fix that?
I am sure pretty late, but I just had the same problem and I figured it out.
What you are probably doing is try to use the resource key inside of the schema.xml of the list.
That is the wrong place to use it. Instead copy the whole line:
<Field ID="{27912FBB-5063-4FF7-9829-B194DDBC7FEB}" Type="Text" Name="PersonName" DisplayName="$Resources:PersonName" Required="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="PersonName" MaxLength="255" />
Inside of the elements.xml of the list where the list definition is. So it should for your example look like this:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ListTemplate
Name="UserList"
Type="100"
BaseType="0"
OnQuickLaunch="TRUE"
SecurityBits="11"
Sequence="410"
DisplayName="UserList"
Description="My List Definition"
Image="/_layouts/15/images/itgen.png"/>
<Field ID="{27912FBB-5063-4FF7-9829-B194DDBC7FEB}" Type="Text"
Name="PersonName" DisplayName="$Resources:PersonName"
Required="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3"
StaticName="PersonName" MaxLength="255" />
</Elements>
If you read carefully this is also documented in the msdn:
https://msdn.microsoft.com/en-us/library/office/fp179919.aspx#LocalizingAppWeb
search for the title "To localize the column names of a custom list" and you should find it.

Custom button on custom tab is always disabled (ribbon bar)

I found a lot of examples how to add custom tab with custom controls on the ribbon bar. But no one works for me. I got the custom tab, but button is always disabled.
There is my current version of code:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<CustomAction
Id="CustomRibbonTab"
Location="CommandUI.Ribbon"
RegistrationId="101"
RegistrationType="List">
<CommandUIExtension>
<CommandUIDefinitions>
<CommandUIDefinition
Location="Ribbon.Tabs._children">
<Tab
Id="Ribbon.CustomTab"
Title="Custom Tab"
Description="Custom Tab !!!"
Sequence="701">
<Scaling
Id="Ribbon.CustomTab.Scaling">
<MaxSize
Id="Ribbon.CustomTab.MaxSize"
GroupId="Ribbon.CustomTab.CustomGroup"
Size="OneLargeTwoMedium"/>
<Scale
Id="Ribbon.CustomTab.Scaling.CustomTabScaling"
GroupId="Ribbon.CustomTab.CustomGroup"
Size="OneLargeTwoMedium" />
</Scaling>
<Groups Id="Ribbon.CustomTab.Groups">
<Group
Id="Ribbon.CustomTab.CustomGroup"
Description="Custom Group!"
Title="Custom Group"
Sequence="62"
Template="Ribbon.Templates.CustomTemplate">
<Controls Id="Ribbon.CustomTab.CustomGroup.Controls">
<Button
Id="Ribbon.CustomTab.CustomGroup.CustomButton"
Command="CustomTab.CustomButtonCommand"
Sequence="115"
Description=""
LabelText="Custom Button"
Image32by32="/_layouts/images/PPEOPLE.GIF"
TemplateAlias="cust1"/>
</Controls>
</Group>
</Groups>
</Tab>
</CommandUIDefinition>
<CommandUIDefinition Location="Ribbon.Templates._children">
<GroupTemplate Id="Ribbon.Templates.CustomTemplate">
<Layout
Title="OneLargeTwoMedium"
LayoutTitle="OneLargeTwoMedium">
<Section Alignment="Top" Type="OneRow">
<Row>
<ControlRef DisplayMode="Large" TemplateAlias="cust1" />
</Row>
</Section>
</Layout>
</GroupTemplate>
</CommandUIDefinition>
</CommandUIDefinitions>
<CommandUIHandlers>
<CommandUIHandler
Command="CustomTab.CustomButtonCommand"
CommandAction="javascript:alert('Hello, world!');"
EnabledScript="javascript:return true;"/>
</CommandUIHandlers>
</CommandUIExtension>
</CustomAction>
</Elements>
I cleaned up the cache. I read about importance of EnabledScripts attribute in the CommandUIHandler. But I always have the same result:
Did anybody have the same issue? Please help!
I checked out a local custom action of mine, and the EnabledScript followed a different pattern:
EnabledScript="javascript:function JustReturnTrue()
{
return true
}
JustReturnTrue();"
If your item is showing up, but always disabled, I bet that's where the problem is.
I think the attribute is optional anyway, if I recall.
I had the same problem, I'm not sure if this is the proper solution, I'm a newbie. I removed the element from feature which scope was set to "Site", added another feature, set the scope to "Web", added my button item in this feature, saved, deployed, enabled the new feature from site features and it worked.

Can't create params for custom component

I'm currently working on a custom joomla component but I fail to get the component wide parameters to work.
The joomla docs say that if you add
to your 'myComponent.xml' file, the parameter should appear in the _components table. I do see my component but there are no params there.
Is there anything I should know? Or anything I might do wrong?
here is test.xml { myComponent.xml }:
<?xml version="1.0" encoding="UTF-8"?>
<install type="component" version="1.5.0">
<name>test</name>
<creationDate>2010-08-05</creationDate>
<author>test</author>
<version>1.0.0</version>
<description>test</description>
<administration>
<menu>Ctest</menu>
<files folder="admin">
<filename>controller.php</filename>
<filename>test.php</filename>
<filename>index.html</filename>
<filename>models/test.php</filename>
<filename>models/index.html</filename>
<filename>views/index.html</filename>
<filename>views/test/index.html</filename>
<filename>views/test/view.html.php</filename>
<filename>views/test/tmpl/default.php</filename>
<filename>views/test/tmpl/index.html</filename>
</files>
</administration>
<params>
<param name="test" type="text" default="" label="test" description="test" />
</params>
</install>
Make sure you're configuring the params correctly in both places config is needed.
In COMPONENTNAME.xml, you need the block you've got above (although I think only 'name' and 'default' are used here).
Also, in admin/config.xml, you'll need something like:
<root>
<params>
<param type="text" name="test" size="30" label="test" description="test" />
</params>
</root>
You'll then need to make sure there's a way to get to these config options, with this in your 'toolbar.COMPONENTNAME.html.php':
JToolBarHelper::preferences('com_magentocatalogue');
Then, a 'config' button should appear in the toolbar for your component. Only once you save some changes will these parameters appear in the #__components.params field.

Resources