Switching between a custom mobile display mode and desktop mode in ASP.NET MVC4 - asp.net-mvc

I would like to create a switch to full site link and switch to mobile link. I don't want to force it to go to either of them by using a session variable. I'd like to know if it's possible to do it automatically by using ViewSwitcher Controller.
Here is what I am using for my custom mobile display mode
public class MobileDisplayMode : DefaultDisplayMode
{
public static readonly List<string> MobileList = new List<string>
{
"Android",
"Mobile",
"Opera Mobi",
"Samsung",
"HTC",
"Nokia",
"Ericsson",
"SonyEricsson",
"iPhone"
,"ipod"
, "symbian"
,"android"
,"windows ce"
,"blackberry"
,"palm"
,"opera mini"
};
public MobileDisplayMode()
: base("Mobile")
{
ContextCondition = (context => IsMobile(context, context.GetOverriddenUserAgent()));
}
private bool IsMobile(HttpContextBase context, string useragentString)
{
return context.Request.Browser.IsMobileDevice || MobileList.Any(val => useragentString.IndexOf(val, StringComparison.InvariantCultureIgnoreCase) >= 0);
}
}
Here is my view switcher code - don't worry about IsMobile Property, it's handled the same way as mobile display mode
if (IsMobile == mobile)
{
HttpContext.ClearOverriddenBrowser();
}
else
{
HttpContext.SetOverriddenBrowser(mobile ? BrowserOverride.Mobile : BrowserOverride.Desktop);
}

Add Jquery.Mobile.Mvc package to the project. A mobile layout will be created. Now every mobile view displays a link to the desktop version. Put the code below in desktop view, so the user can returns to mobile.
#Html.ActionLink("Mobile view", "SwitchView", "ViewSwitcher", new { mobile = true, returnUrl = Request.Url.PathAndQuery }, new { rel = "external" })

Related

Xamarin.Forms Bluetooth Interface choices

I am attempting to write dependency injection methods, with an interface, so that I would be able to really have a single user interface for both Android and UWP.
Processing and testing one feature at a time. The schema is working, but my problem is that on the UWP side, most functions are asynchrone, while they are not on Android.
So my question is, should I "fake" async functions on the android side, and if yes, how?
Here is my example:
using System.Collections.Generic;
using System.Threading.Tasks;
namespace XamarinBTArduinoLed
{
public interface IBlueTooth
{
// as a first test, I will try to get a list of paired devices in both Android and UWP
List<string> PairedDevices();
}
}
This works with Android, but for UWP, it would need to be
public interface IBlueTooth
{
// as a first test, I will try to get a list of paired devices in both Android and UWP
Task<List<string>> PairedDevices();
}
Which does not work for my current Android implementation. So, how should I modify this, to "fake" an asynchrone method, assuming it would be the best choice? Or is there any other way I am not thinking about?
[assembly: Xamarin.Forms.Dependency(typeof(XamarinBTArduinoLed.Droid.BlueToothInterface))]
namespace XamarinBTArduinoLed.Droid
{
public class BlueToothInterface : IBlueTooth
{
public List<string> PairedDevices()
{
List<string> BTItems = new List<string>();
BluetoothAdapter adapter = BluetoothAdapter.DefaultAdapter;
if (adapter == null) throw new Exception("No BlueTooth Adapter Found.");
if (!adapter.IsEnabled)
{
adapter.Enable();
}
//if (!adapter.IsEnabled)
//{
// throw new Exception("BlueTooth adapter is NOT enabled.");
//}
foreach (var item in adapter.BondedDevices)
{
BTItems.Add(item.Name + " - " + item.Type.ToString());
}
return BTItems;
}
}
}
I found what seems to be the best way to go:
-1- I changed the interface to get a Task returned:
public interface IBlueTooth
{
// as a first test, I will try to get a list of paired devices in both Android and UWP
Task<List<string>> PairedDevices();
}
-2- I modified the Android implementation accordingly:
public Task<List<string>> PairedDevices()
{
List<string> BTItems = new List<string>();
BluetoothAdapter adapter = BluetoothAdapter.DefaultAdapter;
if (adapter == null) throw new Exception("No BlueTooth Adapter Found.");
if (!adapter.IsEnabled)
{
adapter.Enable();
}
var t = Task.Factory.StartNew(() =>
{
foreach (var item in adapter.BondedDevices)
{
BTItems.Add(item.Name);
}
return BTItems;
});
return t;
}
-3- I implemented INotifyPropertyChanged to display in XAML
This is now working perfectly, I get my list of USB/Serial devices from both Android and Windows UWP. Will certainly take a while to create the whole process for both platforms, but at least it looks like I am on a good start.
Don't hesitate if you have any comments, recommendations,maybe a better way.....

Xamarin IOS Facebook SDK LoginButton

Im new to Xamarin and IOS development and dont understand why I get this following error:
But first some Information:
Im using this SDK:
https://components.xamarin.com/view/facebookios
and creating my LoginButtin in my ViewController in ViewDidLoad like this:
loginButton = new LoginButton(new CGRect(48, 0, 218, 46))
{
LoginBehavior = LoginBehavior.Native,
ReadPermissions = readPermissions.ToArray()
};
View.AddSubview(button);
But in my Storyboard I get this error message:
Edit: my ViewController.cs
using System;
using System.Collections.Generic;
using UIKit;
namespace FacebookLogin
{
public partial class ViewController : UIViewController
{
List<string> readPermissions = new List<string> { "public_profile" };
LoginButton loginButton;
public ViewController(IntPtr handle) : base(handle)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Perform any additional setup after loading the view, typically from a nib.
loginButton = new LoginButton(new CGRect(48, 0, 218, 46))
{
LoginBehavior = LoginBehavior.Native,
ReadPermissions = readPermissions.ToArray()
};
View.AddSubview(button);
}
public override void DidReceiveMemoryWarning()
{
base.DidReceiveMemoryWarning();
// Release any cached data, images, etc that aren't in use.
}
}
}
Make sure to follow the instructions found on the getting started page. I see an empty component in your solution explorer but just in case, make sure that you installed Xamarin.Facebook.iOS 4.27.1 with nugget. Of course, you also need to set up your facebook app, login, and configure the iOS portion (like setting the BundleID).
Don't create the button in the controller. What you can do is use the storyBoard designer to drop in a regular button. Then, in the properties window click on Class and it should open a dropdown menu. In the selection you should see FBSDKLoginButton, select that class. Give it a name like btnFacebook.
In the codebehind for your controller it will look like this:
string[] readPermissions = { "public_profile" };
public override void ViewDidLoad()
{
base.ViewDidLoad();
btn.LoginBehavior = LoginBehavior.Native;
btnFacebook.ReadPermissions = readPermissions;
// Handle actions once the user is logged in
btnFacebook.Completed += LoginView_Completed;
// Handle actions once the user is logged out
btnFacebook.LoggedOut += LoginView_LoggedOut;
}
private void LoginView_Completed(object sender, LoginButtonCompletedEventArgs e)
{
if (e.Error != null)
{
return;
}
if (e.Result.IsCancelled)
{
return;
}
}
private void LoginView_LoggedOut(object sender, EventArgs e)
{
}
For good measure, clean solution and recompile. The login button won't appear as a facebook login button in your designer but on runtime it will.
As for your error, I don't see anything in your designer so it's curious that it's giving you an error like that. Open the Document Outline (View -> Other Windows -> Document Outline) and see if there's any invisible garbage (elements that aren't being rendered) that has to be deleted.
First Of All! You're on the right Way To solve your issue
and Secondly, I would Suggest you that you have created a controller in the above image you need to create a View Controller File and then add a Login Screen Like a Username named Textbox Then a Password named Textbox and A login Button and then View Controller will automatically created once you save the view And Then Finally, You Save the view Controller By Adding the Following Code
partial void login_TouchUpInside(UIButton sender)
{
var auth = new OAuth2Authenticator(clientId: "YOUR_CLIENT_ID", scope: "", authorizeUrl: new Uri("https://m.facebook.com/dialog/oauth/"), redirectUrl: new Uri("http://www.facebook.com/connect/login_success.html"));
auth.Completed += Auth_Completed;
var ui = auth.GetUI();
PresentViewController(ui, true, null);
}
private async void Auth_Completed(object sender, AuthenticatorCompletedEventArgs e)
{
if (e.IsAuthenticated)
{
var request = new OAuth2Request("POST", new Uri("YOUR Location Where You want to reach After Login"), null, e.Account);
//fb://profile/<id> For opening in Facebook App.
}
DismissViewController(true, null);
}
You See the Above Code And If you Want to Open the Facebook Link In Facebook Application Just Replace URL with
fb://profile/<id>

Change Switch Color in Xamarin.Forms?

I want to change the color of switch in android and created custom renderer just like as one of the post from stack overflow:
Below is the code
public class CustomSwitchRenderer : SwitchRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Switch> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.TextOn = "Yes";
Control.TextOff = "No";
Android.Graphics.Color colorOn = Android.Graphics.Color.Rgb(239, 201, 6);
Android.Graphics.Color colorOff = Android.Graphics.Color.LightGray;
Android.Graphics.Color colorDisabled = Android.Graphics.Color.Gray;
Android.Graphics.Color textColor = Android.Graphics.Color.Black;
Control.SetTextColor (ColorStateList.ValueOf (textColor));
Control.SetTextColor (textColor);
StateListDrawable drawable = new StateListDrawable();
drawable.AddState(new int[] { Android.Resource.Attribute.StateChecked }, new ColorDrawable(colorOn));
drawable.AddState(new int[] { -Android.Resource.Attribute.StateEnabled }, new ColorDrawable(colorDisabled));
drawable.AddState(new int[] { }, new ColorDrawable(colorOff));
Control.ThumbDrawable = drawable;
}
}
}
This code isn't working for me ? Do i need to add some items in drawable folder as well ?
With Forms 2.1, there are now effects which can remove the need for a custom renderer in situations where only minor visual changes are being made. See the linked guide for getting started on using them.
You can create your own control in your UI project:
public class MySwitch : Switch
{
}
After that change your forms where you used Switch control to MySwitch control.
And then you need to tell Xamarin.Forms infrastructure that you are providing renderer for MySwitch control.
In your *.Droid project add following attribute at assembly level (above your namespace declaration or in AssemblyInfo.cs file)
[assembly: ExportRenderer(typeof(MySwitch), typeof(CustomSwitchRenderer))]
For Android you can change the propery "colorAccent" on your "styles.xml" file
<item name="colorAccent">#008000</item>

EPiServer 7 MVC IDisplayModes

Trying to setup a Mobile Channel for use in Edit Mode in EPiServer 7.
Been following this link
http://world.episerver.com/Documentation/Items/Developers-Guide/EPiServer-CMS/7/Content/Display-Channels/
Created an Initialization module
[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class DisplayModesInitialization : IInitializableModule
{
public void Initialize(InitializationEngine context)
{
if (context.HostType == HostType.WebApplication)
{
System.Web.WebPages.DisplayModeProvider.Instance.Modes.RemoveAt(0);
context.Locate.DisplayChannelService()
.RegisterDisplayMode(new DefaultDisplayMode(RenderingTags.Mobile)
{
ContextCondition = (r) => r.Request.Browser.IsMobileDevice
});
}
}
public void Preload(string[] parameters) { }
public void Uninitialize(EPiServer.Framework.Initialization.InitializationEngine context) { }
}
As you can see I tried removing the existing "Mobile" display mode that exists to be replaced with the one created through the EPiServer DisplayChannelService().
Just browsing to the homepage works ok but when I force the userAgent to be a mobile browser it does hit the correct view... i.e. Index.mobile.cshtml
However it appears to still be looking for the _Layout.cshtml instead of _Layout.mobile.cshtml and even at that it fails to find it.
The file "~/Views/Shared/_Layout.cshtml" could not be rendered, because it does not exist or is not a valid page.
Anyone successfully create a mobile IDisplayMode for MVC through the EPiServer DisplayChannelService ?
Also if I explicitly set the layout in the mobile view
#{
Layout = "~/Views/Shared/_Layout.mobile.cshtml";
}
If fails to find that also ?
The file "~/Views/Shared/_Layout.mobile.cshtml" could not be rendered, because it does not exist or is not a valid page.
both the _Layout and _Layout.mobile DO exist in that location ?
Managed to get it working.
Discovered that _ViewStart.cshtml had the following set:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
DisplayModeProvider.Instance.RequireConsistentDisplayMode = true;
}
So I removed the DisplayModeProvider.Instance.RequireConsistentDisplayMode = true; and it now works.
Not sure why this was causing the problem as there are both mobile and desktop views for the homepage and also mobile and desktop layouts ?

MvvmCross Android Dialog bind programmatically

I want to use the Android.Dialog (Cross.UI) in my MvvmCross project. My first approach was to use AutoViews. As this feature is still fairly young, the alternative was to implement the dialog in touch and Droid platforms.
For now i'm just doing this for Droid and I need to programmatically bind the properties of the ViewModel to the elements of the Dialog.
My View and ViewModel code is the following:
View
public class DialogConfigurationView : MvxBindingDialogActivityView<DialogConfigurationViewModel>
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
DroidResources.Initialise(typeof(Resource.Layout));
Root = new RootElement()
{
new Section("Private Configuration")
{
new EntryElement("Name:"),
new EntryElement("Description:"),
new BooleanElement("Active?")
}
};
}
}
ViewModel
public class DialogConfigurationViewModel : MvxViewModel
{
public ConfigurationSet Configuration
{
get { return _configuration; }
set
{
if (_configuration != value)
{
_configuration = value;
RaisePropertyChanged(() => Configuration);
}
}
}
private ConfigurationSet _configuration;
}
My goal is to have a twoway bind the EntryElement("Name:") with the property ViewModel.Configuration.Name.
Can anyone help me with this? Can this be done?
I don't know if there are any monodroid.dialog mvvmcross samples floating around which don't use autoviews!
However.... the basic syntac for binding should be the same as MonoTouch.Dialog - e.g. something like:
new Section("Contact Info")
{
new StringElement("ID", ViewModel.Customer.ID ?? string.Empty),
new EntryElement("Name", "Name").Bind(this, "{'Value':{'Path':'Customer.Name'}}"),
new EntryElement("Website", "Website").Bind(this, "{'Value':{'Path':'Customer.Website'}}"),
new EntryElement("Primary Phone", "Phone").Bind(this, "{'Value':{'Path':'Customer.PrimaryPhone'}}"),
},
new Section("Primary Address")
{
new EntryElement("Address").Bind(this, "{'Value':{'Path':'Customer.PrimaryAddress.Street1'}}"),
new EntryElement("Address2").Bind(this, "{'Value':{'Path':'Customer.PrimaryAddress.Street2'}}"),
new EntryElement("City").Bind(this, "{'Value':{'Path':'Customer.PrimaryAddress.City'}}"),
new EntryElement("State").Bind(this, "{'Value':{'Path':'Customer.PrimaryAddress.State'}}"),
new EntryElement("Zip").Bind(this, "{'Value':{'Path':'Customer.PrimaryAddress.Zip'}}"),
},
from https://github.com/slodge/MvvmCross/blob/vnext/Sample%20-%20CustomerManagement/CustomerManagement/CustomerManagement.Touch/Views/BaseCustomerEditView.cs
Note that in MvvmCross bindings for MonoTouch and MonoDroid, the default binding for things like text edit boxes is generally TwoWay by default.
If you do get a sample running, then please feel free to post it to a gist or to a repo - or to blog about it - looks like we could do with some samples to work from!

Resources