Xamarin - Custom Switch not working - c#

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))]

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;

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.

Xamarin Entry bottom line color doesn`t change

So I am working on Android application. Right now I am creating MainPage where I insert Entry which has the bottom line as always. The bottom line on my previewer is White while on my phone it appears to be Black.
So to fix the issue I decided to play with renderers and see if I can fix it.
I created Class in App called CustomEntryRenderer which inherits from Entry.
Then I created Class in App.Android called CustomEntryRednererAndroid which is supposed to change the color of bottom entry line. But it doesn`t affect it. I tried doing the same with some custom renderers I found on the internet.
For example deleting bottom line didn`t affect the program as well:
removing line
Entry from MainPage.xaml:
<Entry
Grid.Row="4"
Grid.ColumnSpan="2"
TextColor="Silver"
Placeholder="Write Your nickname"
PlaceholderColor="Silver"
/>
CustomEntryRenderer:
public class CustomEntryRenderer : Entry
{
}
CustomEntryRendererAndroid:
[assembly: ExportRenderer(typeof(CustomEntryRenderer), typeof(MyEntryRenderer))]
namespace App3.Droid
{
public class MyEntryRenderer : EntryRenderer
{
public MyEntryRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control == null || e.NewElement == null) return;
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
Control.BackgroundTintList = ColorStateList.ValueOf(Android.Graphics.Color.White);
else
Control.Background.SetColorFilter(Android.Graphics.Color.White, PorterDuff.Mode.SrcAtop);
}
}
}
Top answer for Android
And for some reason also in CustomEntryRendererAndroid.cs I had to use Android.Graphic instead of Xamarin.Forms.Color. But I dont think that is the issue.
I have been trying for a couple of hours now and can`t find the way out of this situation.
Would appreciate any ideas.
In xaml you are using the default Entry control and not your CustomEntryRenderer which is what your renderer is affecting. Also, you might want to rename it because it is not actually your renderer, but your custom control.
To resolve your issue you can either change your renderer typeof(CustomEntryRenderer) to typeof(Entry) to affect all Android entries in your app by default. For example, this worked for my test app for all Entries:
[assembly: ExportRenderer(typeof(Entry), typeof(MyEntryRenderer))]
namespace YourNameSpace
{
public class MyEntryRenderer : EntryRenderer
{
public MyEntryRenderer(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control == null || e.NewElement == null) return;
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
Control.BackgroundTintList = ColorStateList.ValueOf(Android.Graphics.Color.White);
else
Control.Background.SetColorFilter(Android.Graphics.Color.White, PorterDuff.Mode.SrcAtop);
}
}
}
The other option is to switch your xaml code in MainPage to actually use your custom control. For example, <local:CustomEntryRenderer/>
Adding this in the Styles.xml repairs it globally
<item name="colorControlNormal">#1BB8A3</item>"

C#, WPF, Having trouble opening a new window

I've looked through the list of similar questions for this topic and couldn't find any examples which deal with my particular problem.
I'd like to start with the disclaimer that I'm not far off an absolute beginner.
Opening up a window in WPF is quite easy, I've done it before in a previous project and it worked fine.
However, I am struggling to do it again in this new project (login form). I have two classes, MainWindow and CreateAccount.
MainWindow has the event trigger for opening up the CreateAccount window.
private void Button_Click(object sender, RoutedEventArgs e)
{
var account = new CreateAccount();
account.Show();
this.Close();
}
Researching how to open up a new window in WPF gave me snippets very much like this one.
What I want to happen is for, upon triggering the button event, the window I've designed with an account creation form to appear. What instead happens is a blank window pops up with what I can only assume are default dimensions and no border text.
I don't understand how this can be as I specified exactly what I wanted. I don't get any errors either.
The CreateAccount class is mostly just some if statements (I don't want to hunker down with it until I sort out the current issue) and I can't find anything that would cause issue.
Both classes inherit from Window. I took a guess at what might be wrong, thinking 'maybe its an inheritance problem' and so tried to make CreateAccount inherit from MainWindow, but that threw an error which I now understand. Right now I'm lost as to what the problem is and since I don't know that, I can't find out the solution.
Is there anything wrong with the code? Someone suggested that it might be a DataContext issue, but even after looking that up I'm struggling to understand it.
Thank you.
EDIT: Because a lot of people were asking for more code with CreateAccount.xaml.cs(I thought we were only allowed to post snippets):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace Login
{
/// <summary>
/// Interaction logic for CreateAccount.xaml
/// </summary>
public partial class CreateAccount : Window
{
public bool canProceedPass = false;
public bool canProceedUser = false;
public void MakeAccount()
{
InitializeComponent();
}
public void CheckTextInput()
{
if (NewUsername.Text != null && NewPassword.Text != null) {
canProceedUser = true;
}
else
{
canProceedUser = false;
MessageBox.Show("You haven't filled out all the required fields.");
}
}
public void CheckPassInput()
{
if (NewPassword.Text == ConfirmNewPassword.Text)
{
canProceedPass = true;
}else
{
return;
}
}
private void CreateAccountButton_Click(object sender, RoutedEventArgs e)
{
if (canProceedUser == true && canProceedPass == true)
{
//Add username and password to my SqlDb.
}
}
}
}
A constructor should have the same name as your Class with no return type, in your example the constructor should be:
public CreateAccount()
{
InitializeComponent();
}

Compiler Error CS1061

I have the following class...
public class MyCustomLogger
{
public static int DEFAULT_INFO = 0;
public static int DEFAULT_LOGIN = 1;
//etc
public static void Log( ... )
{
doStuff(...);
}
public static void Log( ... , ... )
{
doStuff(...);
}
private static void doStuff(...)
{
//doLots of Stuff
}
So when I call MyCustomLogger.Log(...); from another Custom Class... it works fine. No compile errors...nothing. It just works
When I call it from SuchAndSuch.master code behind... it works fine. No Compile errors...nothing. It just works.
When I call it from SuchAndSuch.ascx code behind... it works fine. No Compile errors...nothing. It just works.
However... when I call it from SuchAndSuch.aspx code behind... it doesn't work. I'm getting 'MyCustomLogger' does not contain a definition for 'Log'
I'm getting this from any aspx page I add it to.
EDIT
Here's a snippet from the aspx pages i'm trying to add it to
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Logout : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//doStuff
}
protected void Button1_Click(object sender, EventArgs e)
{
MyCustomLogger.Log(MyCustomLogger.DEFAULT_INFO);
Has anyone else experienced this?
Here are a few ideas on what might be causing this:
If this is a web site project, which I'm guessing because your extract does not include a namespace, do you have another class in your app_code folder with the MyCustomLogger name?
If this page is in the Master Page, is the Master Page exposing something named MyCustomLogger as a public property and conflicting with the app_code definition?
If this is a web application project, the problem could be because the Namespace declaration is missing on the page.
Is there another type in the page that's MyCustomLogger that there is a conflict (can't resolve the correct type? Can you post any code to help us see the issue?

Categories

Resources