Creating Windows Store App Pages Without XAML - c#

I am writing a C#/XAML Windows Store app and would like to create and navigate to and display a Page entirely from C#. Is this possible? Obviously I can inherit from Page, but, when attempting to Navigate to a derived Page that has no XAML, I get a System.TypeLoadException... "Could not find Windows Runtime type 'Windows.Foundation'".
My thought was this should be possible since XAML translates into a CLR partial class definition, so there's no reason one couldn't do everything in C#. But obviously I missing some sort of framework requirement.
Suggestions?
Right now all I have for the derived Page is
using Windows.UI.Xaml.Controls;
namespace App1 {
public class Page2 : Page {
public Page2 () { }
}
}
And here is the full exception:
Could not find Windows Runtime type 'Windows.Foundation'.
at System.StubHelpers.WinRTTypeNameConverter.GetTypeFromWinRTTypeName(String typeName, Boolean& isPrimitive)
at System.StubHelpers.SystemTypeMarshaler.ConvertToManaged(TypeNameNative* pNativeType, Type& managedType)
at Windows.UI.Xaml.Controls.Frame.Navigate(Type sourcePageType)
at App1.MainPage.<P2>d__2.MoveNext()

I can give an example for a simple page
using System;
using Windows.ApplicationModel.Activation;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
namespace MyApp
{
class Program
{
public static void Main (string[] args)
{
Application.Start((p) => new MyApp());
}
}
class MyApp : Windows.UI.Xaml.Application
{
public MyApp(){}
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
var layoutRoot = new Grid() { Background = new SolidColorBrush(Colors.Blue) };
layoutRoot.Children.Add(new Button() { Content = "Hello!" });
Window.Current.Content = layoutRoot;
Window.Current.Activate();
}
}
}
Replace these paths with the correct items when compiling:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:appcontainerexe /r:"C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Runtime.WindowsRuntime.dll" /r:"C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Runtime.dll" /r:"C:\Windows\System32\WinMetadata\windows.applicationmodel.winmd" /r:"C:\Windows\System32\WinMetadata\windows.ui.winmd" /r:"C:\Windows\System32\WinMetadata\windows.ui.xaml.winmd" /r:"C:\Windows\System32\WinMetadata\windows.media.winmd" MyApp.cs

You can create dynamic XAML using LINQ and XML.
Here's an example on how to create a dynamic TextBlock; you can use the concept to apply it to a Page element:
http://msdn.microsoft.com/en-us/library/cc189044(v=vs.95).aspx

Related

How to change Shell Tabbar height

My Problem:
I use Shell with bottom Tabbar and I simply want to change it height on Android and maybe on iOS.
My Search Results:
I know that the Tabbar is an Android/iOS build in feature with solid specified height.
There seems to be a way to achieve that using a "Custom-Renderer". All projects I have found with this approach don't work with my visual studio (>100 Errors or simply does nothing).
I find it hard to believe that i need >100 rows of code to "only" adjust a height. Could someone provide a working solution to change the Shell Tabbar (bottom tabs) height ?
Edit
Unfourtounately you need to create a custom renderer on each platform project:
Android
MyShellRenderer class
[assembly: ExportRenderer(typeof(App.AppShell), typeof(App.Droid.MyShellRenderer))]
namespace App.Droid
{
public class MyShellRenderer : ShellRenderer
{
public MyShellRenderer(Context context) : base(context)
{
}
protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(ShellItem shellItem)
{
return new MyBottomNavViewAppearanceTracker(this, shellItem);
}
}
}
MyBottomNavViewAppearanceTracker class
class MyBottomNavViewAppearanceTracker : ShellBottomNavViewAppearanceTracker
{
public MyBottomNavViewAppearanceTracker(IShellContext shellContext, ShellItem shellItem) : base(shellContext, shellItem)
{
}
public override void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
{
bottomView.LayoutParameters.Height = 400;
base.SetAppearance(bottomView, appearance);
}
}
Edit:
iOS part credit goes to https://forums.xamarin.com/discussion/169894/how-to-change-shell-height-of-flyout-items-at-the-bottom-of-the-page
iOS
MyShellRenderer class
[assembly: ExportRenderer(typeof(App.AppShell), typeof(App.iOS.MyShellRenderer))]
namespace App.iOS
{
public class MyShellRenderer : ShellRenderer
{
protected override IShellTabBarAppearanceTracker CreateTabBarAppearanceTracker()
{
return new MyCreateTabBarAppearanceTracker();
}
}
}
CreateTabBarAppearanceTracker class
class CreateTabBarAppearanceTracker : ShellTabBarAppearanceTracker
{
public override void SetAppearance(UITabBarController controller, ShellAppearance appearance)
{
UITabBar tabBar = controller.TabBar;
int tabBarHeight = 100;
if (tabBar.Frame.Height != tabBarHeight)
{
tabBar.Frame = new CGRect(tabBar.Frame.X, tabBar.Frame.Y + (tabBar.Frame.Height - tabBarHeight), tabBar.Frame.Width, tabBarHeight);
}
}
}
Extras
You were probably missing some namespaces that would explains the abnormal big number of errors.
could not be found are you missing a using directive or an assembly reference
Usually people don't include namespaces (using statements) in answers because most of the time namespaces are obvious and are handled easily by visual studio intellisense.
Just put or hover the cursor on the red underlined statement and a small tooltip appears
Then click on "Show potential fix" or one of the keyboard shortcuts, select the appropriate fix (usually the first one of the suggested list), in this case intelisense will add the required namespace automatically.
Every Code example i have found has excluded the using directives. in my case i needed those following 3 which i wasnt able to find. Thanks to the answer of #Cfun the code above work with adding:
using Google.Android.Material.BottomNavigation;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

How can I change style of the original tabbed page bar (android with xamarin.forms)?

good morning,
I'm designing my first app in xamarin.forms, but I ran into a problem that is the style of the tabbedpage bar in android.
On iOS it works great, but on Android it has a different display, but I would like to make the homogeneous thing on both operating systems know how to do it?
Screen Android https://ibb.co/cYRLvc4
Screen iOS https://ibb.co/ysnxBr8
You should use a custom effect, first update your android target to 9.0 (and support libraries)
then, create the Routing Effect in your Forms solution:
using Xamarin.Forms;
namespace YourApp
{
public class NoShiftEffect : RoutingEffect
{
public NoShiftEffect() : base("MyEffect.NoShiftEffect")
{
}
}
}
Then, in Android, create a custom renderer:
using Android.Support.Design.BottomNavigation;
using Android.Support.Design.Widget;
using Android.Views;
using yournamespace.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly:ResolutionGroupName ("MyEffect")]
[assembly:ExportEffect (typeof(NoShiftEffect), "NoShiftEffect")]
namespace yournamespace.Droid
{
public class NoShiftEffect : PlatformEffect
{
protected override void OnAttached ()
{
if (!(Container.GetChildAt(0) is ViewGroup layout))
return;
if (!(layout.GetChildAt(1) is BottomNavigationView bottomNavigationView))
return;
// This is what we set to adjust if the shifting happens
bottomNavigationView.LabelVisibilityMode = LabelVisibilityMode.LabelVisibilityLabeled;
}
protected override void OnDetached ()
{
}
}
}
finally, in your tabbde page:
<TabbedPage.Effects>
<local:NoShiftEffect />
</TabbedPage.Effects>

Referencing of classes and namespaces Visual Studio 2017

I noticed for my little project that when importing classes some use full folder reference while otheres don't.
Here is code from project Mini that i am working on.
Models folder
Contains two entities, Auto and Airplane
namespace Mini.Models {
public class Auto {
// code and stuff
}
}
namespace Mini.Models {
public class Airplane {
// code and stuff
}
}
Services folder Contains single service class
namespace Mini.Services
{
public class AutoService : IAutoService {
public bool Get() {
var autoObject = new Models.Auto(); // notice how it references Models folder
var planeObject = new Airplane(); // Same folder but not referencing Models in front of it
// other code
}
}
public interface IAutoService {
bool Get();
// others
}
}
While not a major bugbear, it is still annoying that two classes in same folder get referenced differently, and i cannot figure out why.
Any advice would be appreciated.
Error Message when removing Models folder
Error CS0118: 'Auto' is a namespace but is used like a type (34, 27)
Based on the error message you have provided:
Error CS0118: 'Auto' is a namespace but is used like a type (34, 27)
It would appear that you have a namespace called Auto. Imagine the following example:
namespace MyApp.Auto
{
class Test
{
}
}
namespace MyApp
{
class Auto
{
}
class MyTest
{
private Auto test;
}
}
Because you can see, from the MyApp namespace, both a class called Auto and a namespace called Auto (either namespace MyApp.Auto or simply namespace Auto), C# isn't sure which one you want. As such, it's forcing you to be specific in choosing one or the other.
The easiest solution is to change the MyApp.Auto namespace to something else.
This is not fix but explaining with proper code sample (and why ).
namespace Mini.Models
{
public class Auto
{
// code and stuff
}
}
namespace Mini.Models
{
public class Airplane
{
// code and stuff
}
}
namespace Mini.Auto
{
public class OtherAirplane
{
// code and stuff
}
}
namespace Mini
{
using Mini.Models;
using namespaceAuto = Auto ; /// this also not fix the issue.
class NamespaceIssue
{
void execute()
{
var autoObject = new Auto(); // Error
var planeObject = new Airplane(); // Same folder but not referencing Models in front of it
// other code
}
}
}
now you can see some were in code you have "Mini.Auto" namespace , and it is couching issue.
i tested for VS 2015 have same issue. maybe we have to report to VS team or it is by design .
The issue seemed to be with VS2017 or the way it created the project first time around.
Upon starting brand new project (ASP Core 2.2, Web API, with https enabled and docker disabled), and using same classes the issue was non-existant.

Why am I facing "The type or namespace name 'UnitTestClassBase' could not be found (are you missing a using directive or an assembly reference?)"?

I am using Testleft to automate test scenarios.
Using VS for the 1st time.
This is the code:
############################################################################
using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;
using System.Text;
using SmartBear.TestLeft;
using SmartBear.TestLeft.TestObjects;
using SmartBear.TestLeft.TestObjects.Win;
using System.IO;
namespace TestLeftProject1
{
[TestClass]
public class TestLeftTest : UnitTestClassBase
{
#region Class initializers
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
UnitTestClassBase.InitializeClass(context);
}
[ClassCleanup]
public static void ClassCleanUp()
{
UnitTestClassBase.FinalizeClass();
}
#endregion
[TestMethod]
public void TestMethod1()
{
// Runs the Notepad application
IProcess process = Driver.Applications.Run("notepad.exe");
// Gets Notepad's edit box
IWinTextEdit edit = process.Find<ITopLevelWindow>(new WindowPattern()
{
WndClass = "Notepad"
}).Find<IWinTextEdit>(new WindowPattern()
{
WndClass = "Edit"
});
// Simulates a mouse click in Notepad
edit.Click();
// Simulates text input in Notepad
string inputText = "test";
edit.SetText(inputText);
// Verifies the text that Notepad contains
Assert.AreEqual(inputText, edit.wText);
// Posts messages to the TestLeft test log
Driver.Log.Screenshot(edit, "Notepad's edit box screenshot");
Driver.Log.Warning("A warning message");
// Saves the TestLeft test log
string logPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), DateTime.Now.ToString("MM_dd_yyyy_H_mm_ss"));
Driver.Log.Save(logPath, Log.Format.Html);
}
}
}
I have tried other solutions like changing the target framework from 4.5 to 4 and 4.5.1.
I am not sure what to do. I am new to VS. Please help
you need to add a class with the name UnitTestClassBase.
Anyway have a look how to write good unit tests. You should also use the pattern Arrange, Act and Assert
You are most likely missing a reference to the assembly SmartBear. To validate this, go to the references in the solution explorer and check this assembly is referenced. If it isn't, add it as a reference.

Xamarin - Custom Switch not working

So this is the very first time I try to create a custom renderer. I followed this thread here: https://forums.xamarin.com/discussion/32264/how-can-i-change-switch-text-color-android. I took a look at the first guy who placed an example code. I tried to use it with my own renderer but It gives the following error:
Type or namespace 'controls' doesn't exist in 'saleskicker'
here is my code:
using System;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms;
using SalesKicker;
[assembly:ExportRenderer(typeof(SalesKicker.Controls.CustomSwitch), typeof(CustomSwitchRenderer))]
namespace SalesKicker
{
public class CustomSwitchRenderer : SwitchRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.TextOn = "AAN";
Control.TextOff = "UIT";
Control.SetTextColor(Color.White);
}
if (Control.Checked == true)
{
Control.SetBackgroundColor(Color.Green);
}
}
}
}
However, the error didn't show up when I had the class inside a folder called 'CustomRenderers'. But I think this shouldn't be such a big deal. What am I doing wrong here? Can someone please help me?
If you just want to change the Color, you don't need a CustomControl. And then you can replace the default renderer with your own.
[assembly:ExportRenderer(typeof(Switch), typeof(CustomSwitchRenderer))]

Categories

Resources