I want to create a custom control for a button. However wow can i override the visibility of the button?
For example if the access level of the user is false then it will hide the button.
Here is my coding
public override void Visible()
{//Get access right from session
blcAccessLevel accessLevel = (blcAccessLevel)HttpContext.Current.Session[gbcAccessLevel.sessionAcl];
if (accessLevel.Read_Access == true)
{
base.Visible = true;//error occu
}
else
{
base.Visible = false;
}
}
It return me the error.Error 'blcCustomControl.cusAclReadButton.Visible()': cannot override because 'System.Web.UI.Control.Visible' is not a function By the way, should I implement the get set method?
public class MyButton : Button
{
public new bool Visible
{
get
{
return (blcAccessLevel)HttpContext.Current.Session[gbcAccessLevel.sessionAcl].ReadAccess;
}
}
}
Related
How could I detect tab was touched in xamarin forms TabbedPage?
(which is different from page changed detection which I figured how to detect)
Here is why:
I'm trying to work around a rather ugly tabbed page overflow UI
(the ugly scroller that shows up on the right over the tabbar
whenever there are >5 tabs)
So the 5th tab press shows a custom menu, second press hides that menu, etc.
Thanks!
If you are trying to find which page is selected in TabbedPage you could do it in this way.
With Index value you can perform whatever action you want..
Event for detecting page no:
this.CurrentPageChanged += (object sender, EventArgs e) => {
var i = this.Children.IndexOf(this.CurrentPage);
System.Diagnostics.Debug.WriteLine("Page No:"+i);
};
It has been a while since this was asked but just in case here is an answer.
Perform an action when a tab is tapped is the same as when:
The tab has changed
The tab is "reselected"
So for the first one you can use #femil-shajin 's answer or as I do here which is more direct and for the second one you need to make some custom renderers for the TabbedPage:
public class MyTabbedPage : TabbedPage
{
...
protected override void OnCurrentPageChanged()
{
// do whatever
}
public void OnTabReselected()
{
// do whatever
}
...
}
Then on Android:
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedRenderer))]
namespace MyNamespace.Droid.Renderers
{
public class CustomTabbedRenderer : TabbedPageRenderer, NavigationBarView.IOnItemReselectedListener
{
...
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
GetBottomNavigationView()?.SetOnItemReselectedListener(this);
}
}
private BottomNavigationView GetBottomNavigationView()
{
// this may need to change on some cases
for (var i = 0; i < ViewGroup.ChildCount; i++)
{
var childView = ViewGroup.GetChildAt(i);
if (childView is ViewGroup viewGroup)
{
for (var j = 0; j < viewGroup.ChildCount; j++)
{
var childRelativeLayoutView = viewGroup.GetChildAt(j);
if (childRelativeLayoutView is BottomNavigationView bottomNavigationView)
{
return bottomNavigationView;
}
}
}
}
return null;
}
public void OnNavigationItemReselected(IMenuItem item)
{
if (Element is MyTabbedPage tabbedPage)
{
tabbedPage.OnTabReselected();
}
}
...
}
}
And on iOS:
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedRenderer))]
namespace MyNamespace.iOS.Renderers
{
public class CustomTabbedRenderer : TabbedRenderer
{
private UITabBarItem _previousSelectedItem;
...
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
if (SelectedIndex < TabBar.Items.Length)
{
_previousSelectedItem = TabBar.Items[SelectedIndex];
}
}
public override void ItemSelected(UITabBar tabbar, UITabBarItem item)
{
if (_previousSelectedItem == item && Element is MyTabbedPage tabbedPage)
{
tabbedPage.OnTabReselected();
}
_previousSelectedItem = item;
}
...
}
}
Source: Part of this was based on this page
i would like to enable/disable buttons according to the current active userlevel. i have a property in the MV for the current userlevel:
public int CurrentUserLevel
{
get { return _CurrentUserLevel; }
set
{
if (_CurrentUserLevel == value)
return;
_CurrentUserLevel = value;
RaisePropertyChanged("CurrentUserLevel");
}
}
how can i enable/disable the button if this value is >=x?
You'll need to create a property in your ViewModel, for which the Button's IsEnabled property can bind to. Make sure that the new property's PropertyChanged event is raised whenever the CurrentUserLevel is changed.
public int CurrentUserLevel
{
get { /*...*/ }
set
{
/*...*/
RaisePropertyChanged("CurrentUserLevel");
RaisePropertyChanged("IsAllowedToDoSomething"); //dependant property
}
}
public bool IsAllowedToDoSomething
{
get { return CurrentUserLevel > 1; }
}
And in your XAML:
<Button IsEnabled="{Binding IsAllowedToDoSomething}" Content="Click me!" />
I am trying to track navigation between a number of Web Forms in ASP.NET. I've tried the client side back navigation using the following:
<asp:Button ID="BackButton" runat="server" Text="Back"
OnClientClick="JavaScript:window.history.back(1);return false;" />
Unfortunately this does not work for my scenario due to postbacks going on. My scenario has a number of Web Forms:
Page1.1
Page1.2
Page2
Page3
Navigating forward through the pages works similarly to a wizard. There are 2 starting points - from Page1.1 and Page1.2.
Page1.1 -> Page2 -> Page3
Page1.2 -> Page2 -> Page3
So clicking back buttons will have the following navigation:
Page3 -> Page2
Page2 -> Page1.1
Page2 -> Page1.2
There are additional parameters passed between the pages which need to be maintained.
I am currently looking at maintaining something in the Session to maintain the current call stack which somewhat works however, I am getting a build up of referrer urls. At the minute I am just trying to conceptualise this.
I am running this in SharePoint as Application Pages, however each page is essentially an ASP.NET page for the sake of this example.
So I have introduced an abstract class for each Page:
public abstract class SecureLayoutsPageBase : System.Web.UI.Page
{
private PageController _pageController;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_pageController = (PageController)Session["PageController"];
if (_pageController == null)
{
_pageController = new PageController();
Session["PageController"] = _pageController;
}
if (!Page.IsPostBack && Page.Request.UrlReferrer != null)
{
this.PageController.History.Push(Page.Request.UrlReferrer.ToString());
}
}
protected PageController PageController
{
get
{
return _pageController;
}
}
}
Which has an instance of PageController:
[Serializable()]
public class PageController
{
private Stack<string> _history = new Stack<string>();
public void Previous(HttpResponse response)
{
string previous = _history.Pop();
response.Redirect(previous);
}
public Stack<string> History
{
get
{
return _history;
}
}
}
Then each page will call the PageController.Previous in the server side event handler for the back button click:
protected void BackButton_Click(object sender, EventArgs e)
{
this.PageController.Previous(this.Response);
}
This issue with this is that calling PageController.Previous still results in the Url being added to the stack. I am just wondering if there is a way to prevent the url getting added when back has been clicked. Or alternative solutions...
History(-1) wont work, because this will include postbacks. Just set the button href dependant on whatever page you're on. If you know itsloaded page 3, set the back button to page 2
OK... couple of tweaks to get my scenario working. Not keen on this solution so any others would be good.
Change to SecureLayoutsPageBase:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_pageController = (PageController)Session["PageController"];
if (_pageController == null)
{
_pageController = new PageController();
Session["PageController"] = _pageController;
}
if (!Page.IsPostBack && Page.Request.UrlReferrer != null && Page.Request.Url.ToString() != this.PageController.PreviousUrl)
{
this.PageController.AddHistory(Page.Request.UrlReferrer.ToString());
}
}
Change to PageController:
[Serializable()]
public class PageController
{
private Stack<string> _history = new Stack<string>();
private string _previous;
public void Previous(HttpResponse response)
{
_previous = _history.Pop();
response.Redirect(_previous);
}
public void AddHistory(string url)
{
if(url != _previous)
{
_history.Push(url);
}
}
public Stack<string> History
{
get
{
return _history;
}
}
public string PreviousUrl
{
get
{
return _previous;
}
}
}
From the examples at Xamarin.com you can build basic M.T. Dialog apps, but how do you build a real life application?
Do you:
1) Create a single DialogViewController and tree every view/RootElement from there or,
2) Create a DialogViewController for every view and use the UINavigationController and push it on as needed?
Depending on your answer, the better response is how? I've built the example task app, so I understand adding elements to a table, click it to go to the 'next' view for editing, but how to click for non-editing? How to click a button, go next view if answer is number 1?
Revised:
There is probably no one right answer, but what I've come up with seems to work for us. Number 2 from above is what was chosen, below is an example of the code as it currently exists. What we did was create a navigation controller in AppDelegate and give access to it throughout the whole application like this:
public partial class AppDelegate : UIApplicationDelegate
{
public UIWindow window { get; private set; }
//< There's a Window property/field which we chose not to bother with
public static AppDelegate Current { get; private set; }
public UINavigationController NavController { get; private set; }
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
Current = this;
window = new UIWindow (UIScreen.MainScreen.Bounds);
NavController = new UINavigationController();
// See About Controller below
DialogViewController about = new AboutController();
NavController.PushViewController(about, true);
window.RootViewController = NavController;
window.MakeKeyAndVisible ();
return true;
}
}
Then every Dialog has a structure like this:
public class AboutController : DialogViewController
{
public delegate void D(AboutController dvc);
public event D ViewLoaded = delegate { };
static About about;
public AboutController()
: base(about = new About())
{
Autorotate = true;
about.SetDialogViewController(this);
}
public override void LoadView()
{
base.LoadView();
ViewLoaded(this);
}
}
public class About : RootElement
{
static AboutModel about = AboutVM.About;
public About()
: base(about.Title)
{
string[] message = about.Text.Split(...);
Add(new Section(){
new AboutMessage(message[0]),
new About_Image(about),
new AboutMessage(message[1]),
});
}
internal void SetDialogViewController(AboutController dvc)
{
var next = new UIBarButtonItem(UIBarButtonSystemItem.Play);
dvc.NavigationItem.RightBarButtonItem = next;
dvc.ViewLoaded += new AboutController.D(dvc_ViewLoaded);
next.Clicked += new System.EventHandler(next_Clicked);
}
void next_Clicked(object sender, System.EventArgs e)
{
// Load next controller
AppDelegate.Current.NavController.PushViewController(new IssuesController(), true);
}
void dvc_ViewLoaded(AboutController dvc)
{
// Swipe location: https://gist.github.com/2884348
dvc.View.Swipe(UISwipeGestureRecognizerDirection.Left).Event +=
delegate { next_Clicked(null, null); };
}
}
Create a sub-class of elements as needed:
public class About_Image : Element, IElementSizing
{
static NSString skey = new NSString("About_Image");
AboutModel about;
UIImage image;
public About_Image(AboutModel about)
: base(string.Empty)
{
this.about = about;
FileInfo imageFile = App.LibraryFile(about.Image ?? "filler.png");
if (imageFile.Exists)
{
float size = 240;
image = UIImage.FromFile(imageFile.FullName);
var resizer = new ImageResizer(image);
resizer.Resize(size, size);
image = resizer.ModifiedImage;
}
}
public override UITableViewCell GetCell(UITableView tv)
{
var cell = tv.DequeueReusableCell(skey);
if (cell == null)
{
cell = new UITableViewCell(UITableViewCellStyle.Default, skey)
{
SelectionStyle = UITableViewCellSelectionStyle.None,
Accessory = UITableViewCellAccessory.None,
};
}
if (null != image)
{
cell.ImageView.ContentMode = UIViewContentMode.Center;
cell.ImageView.Image = image;
}
return cell;
}
public float GetHeight(UITableView tableView, NSIndexPath indexPath)
{
float height = 100;
if (null != image)
height = image.Size.Height;
return height;
}
public override void Selected(DialogViewController dvc, UITableView tableView, NSIndexPath indexPath)
{
//base.Selected(dvc, tableView, path);
tableView.DeselectRow(indexPath, true);
}
}
#miquel
The current idea of a workflow is an app that starts with a jpg of the Default.png that fades into the first view, with a flow control button(s) that would move to the main app. This view, which I had working previous to M.T.D. (MonoTouch.Dialog), which is a table of text rows with an image. When each row is clicked, it moves to another view that has the row/text in more detail.
The app also supports in-app-purchasing, so if the client wishes to purchase more of the product, then switch to another view to transact the purchase(s). This part was the main reason for switching to M.T.D., as I thought M.T.D. would be perfect for it.
Lastly there would be a settings view to re-enable purchases, etc.
PS How does one know when the app is un-minimized? We would like to show the fade in image again.
I have been asking myself the same questions. I've used the Funq Dependency Injection framework and I create a new DialogViewController for each view. It's effectively the same approach I've used previously developing ASP.NET MVC applications and means I can keep the controller logic nicely separated. I subclass DialogViewController for each view which allows me to pass in to the controller any application data required for that particular controller. I'm not sure if this is the recommended approach but so far it's working for me.
I too have looked at the TweetStation application and I find it a useful reference but the associated documentation specifically says that it isn't trying to be an example of how to structure a MonoTouch application.
I use option 2 that you stated as well, it works pretty nicely as you're able to edit the toolbar options on a per-root-view basis and such.
Option 2 is more feasible, as it also gives you more control on each DialogViewController. It can also helps if you want to conditionally load the view.
I have a button which I use for sending a message. When the message text is empty, it should not be possible to click the button.
This is all fine and not an issue. The only thing that is bugging me is the fact that I can disable the send button but the image does not get disabled (like I would expect).
Is there a way to do this elegantly because I don't want to provide a sendicon_disabled.png and change it myself (I don't think this should be my job).
You can use the following button for that:
package
{
import mx.controls.Button;
import mx.core.mx_internal;
use namespace mx_internal;
public class IconButton extends Button
{
private var enabledChanged:Boolean = false;
override public function set enabled(value:Boolean):void
{
if (super.enabled == value)
{
return;
}
super.enabled = value;
enabledChanged = true;
invalidateDisplayList();
}
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (enabledChanged)
{
if (!enabled && currentIcon)
{
currentIcon.alpha = 0.5;
}
enabledChanged = false;
}
}
}
}
You can use your custom alpha value or move it to separate style.