i'm developing an ios app with xamarin.
i created a button in this way:
var myBtn = new UIButton(UIButtonType.System);
myBtn.Frame = new CGRect(xImg, 1180, 200, 100);
myBtn.SetTitleColor(UIColor.Yellow, UIControlState.Normal);
myBtn.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
myBtn.TouchUpInside += delegate
{
NavController.PushViewController(new WebViewController(), false);
};
the WebViewController contains a webservice call, so it spends some seconds to detect data.
When i Tap on the button, the app calls the webservice first, then it changes the UiViewController. In this way I can't implement the Loading Overlay class
So i need that, when i tap the button, first it shows the empty UiViewController (with the LoadingOverlay), and then, when the webservice call is complete, show the remaining components.
This is the WebViewController:
public override void ViewDidLoad()
{
base.ViewDidLoad();
Title = "MyTitle";
var logo = new UIImageView(new CGRect(20, 50, sizes.Width - 40, 130));
logo.Image = UIImage.FromBundle("logo.jpg");
View.BackgroundColor = UIColor.Black;
scrollView = new UIScrollView(new CGRect(20, 180, UIScreen.MainScreen.Bounds.Width - 40, UIScreen.MainScreen.Bounds.Height - 180));
scrollView.BackgroundColor = UIColor.Black;
.........
List<UIImage> imagesList = getImagesList(urlG);
int count = 0;
List<UIImageView> imageViewList = new List<UIImageView>();
List<UIButton> btnList = new List<UIButton>();
nfloat imgS = getImgSizes();
nfloat imgY = 0;
......
for (int i = 0; i < imageViewList.Count; i++)
{
scrollView.AddSubview(imageViewList[i]);
scrollView.AddSubview(btnList[i]);
}
scrollView.ContentSize = new CGSize(UIScreen.MainScreen.Bounds.Width - 40, ((imagesList.Count / 4) * getImgSizes()) + 150);
View.AddSubview(logo);
Add(scrollView);
View.Add(loadPop);
.....
}
}
Related
I create a panel and fill it on all the surface of the form and i create a label too for bring it to front of the panel but the only thing it's showing is the panel, i see the hitbox of the label that's all.
private void drawPanels()
{
// I setup my label
Label username = new Label();
Label usernameText = new Label();
var usernameSize = new Size(84, 21);
var usernamePos = new Point(11, 4);
int usernameOffset = 60;
// I setup my panel here
Panel panel = new Panel();
var panelSize = new Size(490, 50);
var panelPos = new Point(12, 12);
int panelVertOffset = 60;
for (int i = 0; i < 2; i++)
{
// I draw the panel
panel.Size = panelSize;
panel.Location = panelPos;
panel.BackColor = Color.FromArgb(35, 35, 35);
parent.Controls.Add(panel);
parent.Controls.Add(username);
// I draw the label
username.Size = new Size(84, 21);
username.Location = new Point(11, 4);
username.BackColor = Color.FromArgb(35, 35, 35);
username.ForeColor = Color.FromArgb(35, 35, 35);
username.Text = "Username:";
// Im trying to fix the problem with this function but it isn't work
username.BringToFront();
// Duplicate the panel and place it down ( y+60 )
panelPos.Offset(0, panelVertOffset);
usernamePos.Offset(0, usernameOffset);
}
}
That's the result i get
For my program I am creating a register system to mark attendance for students. I start by taking the students in list student and creating a panel for each with an accompanying name textbox.
the next step is to add 3 radio buttons to each panel however it doesn't seem to work as intended and I don't know why. Can you not use a list of RadioButtons in the way I have.
To cover any confusion the studentlist is a test at the moment with them being names 1 - 10 and with regards to the buttons one would resemble present, absent and the other late.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
studentlist.Add(i.ToString());
}
drawregisterpanels();
}
List<string> studentlist = new List<string>();
public void drawregisterpanels()
{
TextBox[] StudentNames = new TextBox[studentlist.Count];
Panel[] RowOfChoice = new Panel[studentlist.Count];
int width = 100;
int height = 25;
for (int k = 0; k < RowOfChoice.Length; k++)
{
StudentNames[k] = new TextBox
{
Text = studentlist[k],
Size = new Size(width, height),
Location = new Point(0, height * k),
};
RowOfChoice[k] = new Panel
{
Name = k.ToString(),
Size = new Size(width, height),
Location = new Point(StudentNames[k].Width, height * k),
BackColor = Color.CadetBlue,
BorderStyle = BorderStyle.Fixed3D,
};
RegisterPanel.Controls.Add(StudentNames[k]);
RegisterPanel.Controls.Add(RowOfChoice[k]);
addradiobuttons(k, RowOfChoice);
}
}
List<RadioButton> RegisterStatusChoice = new List<RadioButton>();
void addradiobuttons(int panelno,Panel[] RowOfChoice)
{
int Width = RowOfChoice[panelno].Width / 3;
int Height = RowOfChoice[panelno].Height;
for (int p = 0; p < 3; p++)
{
Console.WriteLine((panelno*3)+p);
RegisterStatusChoice[(panelno * 3) + p] = new RadioButton
{
Size = new Size(Width, Height),
Location = new Point(Width * p, 0),
CheckAlign = ContentAlignment.MiddleCenter,
};
RowOfChoice[panelno].Controls.Add(RegisterStatusChoice[(panelno * 3) + p]);
}
}
}
As can be seen before the radio buttons are attempted to be added it works as intended
However I don't know why this error occurs as the integers provided shouldn't be out of the range
You need to add the RadioButtons to the list, you just initialize it but don't add it. Note that a list is different to an array. If you initialize it with a capacity it's still empty and you can't access items at a given index. You are using the default constructor anyway that just creates an empty list with the default capacity(4). So you need to add them first.
So instead of:
RegisterStatusChoice[(panelno * 3) + p] = new RadioButton
{
Size = new Size(Width, Height),
Location = new Point(Width * p, 0),
CheckAlign = ContentAlignment.MiddleCenter,
};
RowOfChoice[panelno].Controls.Add(RegisterStatusChoice[(panelno * 3) + p]);
use this:
RadioButton rb = new RadioButton
{
Size = new Size(Width, Height),
Location = new Point(Width * p, 0),
CheckAlign = ContentAlignment.MiddleCenter,
};
RegisterStatusChoice.Add(rb);
RowOfChoice[panelno].Controls.Add(rb);
I have a large database and I need to organize searching accounts from my application. App is loaded data dynamically. NetworkBackgroundWorker is a class that send requeste to the server (with database). This class uses BackgroundWorker for waiting answer in the background.
//Callback method
Action<string> refToSP = SetParticipants;
//Send a request to the server for getting account data
NetworkBackgroundWorker.InvokeService(
query,
requestURL,
methodName,
refToSP);
The SetParticipants method is using another BackgroundWorker for add new accounts to the mainStackLayout in the background.
//SetParticipants - This is a method that will be call from the BackgroundWorker
//participantsJSON - Data represented as a JSON code
public void SetParticipants(string participantsJSON)
{
backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork +=
new DoWorkEventHandler(backgroundWorker_DoWork);
backgroundWorker.RunWorkerAsync(participantsJSON);
}
And the method for adding new accounts to the MainStackLayout
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
List<ParticipantsTable> participantsTable =
JsonSerializer.Deserialize<List<ParticipantsTable>>(e.Argument.ToString());
for (int i = 0; i < participantsTable.Count; i++)
{
BoxView boxView = new BoxView();
boxView.BackgroundColor = Color.LightGreen;
Label labelParticipantName = new Label();
labelParticipantName.Text =
participantsTable[i].FirstName_ + " " + participantsTable[i].LastName_;
labelParticipantName.FontSize = 20;
labelParticipantName.VerticalOptions = LayoutOptions.StartAndExpand;
labelParticipantName.HorizontalOptions = LayoutOptions.StartAndExpand;
Label labelParticipantPhone = new Label();
labelParticipantPhone.Text =
participantsTable[i].PhoneNumber_;
labelParticipantPhone.FontSize = 20;
labelParticipantPhone.VerticalOptions = LayoutOptions.StartAndExpand;
labelParticipantPhone.HorizontalOptions = LayoutOptions.StartAndExpand;
Label labelSelect = new Label();
labelSelect.Text = "Select: ";
labelSelect.FontSize = 20;
labelSelect.VerticalOptions = LayoutOptions.Start;
labelSelect.HorizontalOptions = LayoutOptions.Start;
CheckBox checkBox = new CheckBox();
checkBox.VerticalOptions = LayoutOptions.Start;
checkBox.HorizontalOptions = LayoutOptions.Start;
StackLayout stackLayout = new StackLayout();
stackLayout.Orientation = StackOrientation.Horizontal;
stackLayout.Children.Add(labelSelect);
stackLayout.Children.Add(checkBox);
var container = new Grid();
container.Children.Add(boxView, 0, 0);
container.Children.Add(labelParticipantName, 0, 0);
container.Children.Add(labelParticipantPhone, 0, 1);
container.Children.Add(stackLayout, 0, 2);
Grid.SetRowSpan(boxView, 3);
mainStackLayout.Children.Add(container);
}
}
I do not have idea why, but scrolling is working not smoothly in the app.
https://www.youtube.com/watch?v=x1iEHFPINnE
How to make smooth scrolling?
#Lucas Zhang - "Put container in the ScrollView or ListView instead of StackLayout".
This recommendation helped to get rid of the scroll jumping.
Okay,This is What I would like to do in MvvmCross without any plugins just native code. I did find a Tutorial on how to it, but I would like it in MvvmCross.iOS Have a look at what I would like to do in MvvmCross.iOS
Please advise or forward a better tutorial for MvvmCross.iOS
points to remember
The hamburger menu should have a draggable effect like the image I have linked
what I have tried
ViewDidLoad() -->
UIPanGestureRecognizer gesture = new UIPanGestureRecognizer();
gesture.AddTarget(() => HandleDrag(gesture));
this.View.AddGestureRecognizer(gesture);
panGestureRecognizer = new UIScreenEdgePanGestureRecognizer ( HandleSwipeRight);
panGestureRecognizer.Edges = UIRectEdge.Left;
this.View.AddGestureRecognizer(panGestureRecognizer);
HandleDrag() -->
protected void HandleDrag(UIPanGestureRecognizer recognizer)
{
PointF offset2 = (System.Drawing.PointF)recognizer.TranslationInView(View);
if (recognizer.State != (UIGestureRecognizerState.Cancelled | UIGestureRecognizerState.Failed
| UIGestureRecognizerState.Possible))
{
Console.WriteLine("Here");
// NEED TO LOAD ANOTHER VIEW HERE
openMenu();
}
}
openMenu() -->
public void openMenu()
{
viewBlack.Hidden = false;
this.view.Hidden = false;
UIView.Animate(
duration: 0.3,
delay: 0,
options: UIViewAnimationOptions.CurveEaseInOut |
UIViewAnimationOptions.Autoreverse,
animation: () =>
{
this.view.LayoutIfNeeded();
this.viewBlack.Alpha = this.maxBlackViewAlpha = 0.5f;
},
completion: () =>
{
panGestureRecognizer.Enabled = false;
}
);
}
hideMenu() -->
public void closeMenu(){
UIView.Animate(
duration: 0.3,
delay: 0,
options: UIViewAnimationOptions.CurveEaseInOut |
UIViewAnimationOptions.Autoreverse,
animation: () =>
{
this.view.LayoutIfNeeded();
this.viewBlack.Alpha = 0;
},
completion: () =>
{
panGestureRecognizer.Enabled = true;
viewBlack.Hidden = true;
view.Hidden = true;
}
);
}
My Custom Hamburger menu UIView -->
view = new UIView();
view.Frame = new CGRect(0, 0, UIScreen.MainScreen.Bounds.Width / 1.1, UIScreen.MainScreen.Bounds.Height);
var gradientLayer = new CAGradientLayer();
gradientLayer.Colors = new[] { UIColor.FromRGB(64, 0, 128).CGColor, UIColor.FromRGB(0, 0, 128).CGColor };
gradientLayer.Locations = new NSNumber[] { 0, 1 };
gradientLayer.Frame = view.Frame;
view.BackgroundColor = UIColor.Clear;
view.Layer.AddSublayer(gradientLayer);
var viewline = new UIView();
viewline.Frame = new CGRect(20, 60, 100, 1);
viewline.BackgroundColor = UIColor.White;
var bb = new UIBarButtonItem();
var Allbutton = new UIButton(new CGRect(0, 20, 135, 20));
Allbutton.SetTitleColor(UIColor.Black, UIControlState.Normal);
Allbutton.TitleLabel.BackgroundColor = UIColor.White;
Allbutton.SetTitle("Login", UIControlState.Normal);
var myPrefbutton = new UIButton(new CGRect(0, 120, 135, 20));
myPrefbutton.SetTitleColor(UIColor.Black, UIControlState.Normal);
myPrefbutton.SetTitle("Logout", UIControlState.Normal);
myPrefbutton.TitleLabel.BackgroundColor = UIColor.White;
view.BackgroundColor = UIColor.White;
view.Add(Allbutton);
view.Add(viewline);
view.Add(myPrefbutton);
view.Hidden = true;
this.View.AddSubviews(view);
this is the only code I was able to convert into MvvmCross.iOS from tutorial(SWIFT) and it's works but
I cannot drag the menu to show, what happens is that it load up normally and it's fast
Note!!! I am not using any Storyboards or nib files just using pure code for this hamburger menu
please has a good look at the .gif notice that the menu is draggable which makes it's animation slow and not fast.
if I have confused you please don't be sad I have just started coding in iOS and MvvmCross... I'm still a noob
Got it to work
first had to create a UIVew class -->
SideMenuView : MvxViewController
then set the X to minus... it will be zero if a user selects the navbaritem I also added a overlay UIView
viewBlack = new UIView();
viewBlack.Frame = new CGRect(0, 0, UIScreen.MainScreen.Bounds.Width, UIScreen.MainScreen.Bounds.Height);
viewBlack.BackgroundColor = UIColor.Black;
viewBlack.Alpha = 0.5f;
viewBlack.Hidden = true;
this.View.AddSubviews(viewBlack);
Hi I am looking to print a StackPanel that contains a listbox which can contain an infinite number of items and therefore needs to print over multiple pages. I found this code online and it works fine.
public static FixedDocument GetFixedDocument(FrameworkElement toPrint, PrintDialog printDialog)
{
if (printDialog == null)
{
printDialog = new PrintDialog();
}
var capabilities = printDialog.PrintQueue.GetPrintCapabilities(printDialog.PrintTicket);
var pageSize = new Size(printDialog.PrintableAreaWidth, printDialog.PrintableAreaHeight);
var visibleSize = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
var fixedDoc = new FixedDocument();
//If the toPrint visual is not displayed on screen we neeed to measure and arrange it
toPrint.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
toPrint.Arrange(new Rect(new Point(0, 0), toPrint.DesiredSize));
//
var size = toPrint.DesiredSize;
//Will assume for simplicity the control fits horizontally on the page
double yOffset = 0;
while (yOffset < size.Height)
{
var vb = new VisualBrush(toPrint)
{
Stretch = Stretch.None,
AlignmentX = AlignmentX.Left,
AlignmentY = AlignmentY.Top,
ViewboxUnits = BrushMappingMode.Absolute,
TileMode = TileMode.None,
Viewbox = new Rect(0, yOffset, visibleSize.Width, visibleSize.Height)
};
var pageContent = new PageContent();
var page = new FixedPage();
((IAddChild)pageContent).AddChild(page);
fixedDoc.Pages.Add(pageContent);
page.Width = pageSize.Width;
page.Height = pageSize.Height;
var canvas = new Canvas();
FixedPage.SetLeft(canvas, capabilities.PageImageableArea.OriginWidth);
FixedPage.SetTop(canvas, capabilities.PageImageableArea.OriginHeight);
canvas.Width = visibleSize.Width;
canvas.Height = visibleSize.Height;
canvas.Background = vb;
page.Children.Add(canvas);
yOffset += visibleSize.Height;
}
return fixedDoc;
}
However this causes certain items of a listbox to be cut off at the bottom of a page and continued on the next page (as shown below). Is it possible to modify this code in any way to determine the size of the page and if the current listboxitem does not fit onto this page that it starts on the next page? Quite new to all this so any help would be greatly appreciated.
I had a similiar task once and came up with this code, which uses a 'dummy' renderer to determine the height of the element up front and then either adds it to the current page or creates a new one. For sure, that's not a very beautiful solution, but it did the job at the time. Maybe you can take sth. away from it.
Size A4Size = new Size(793.92, 1122.24);
Size InfiniteSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
var pages = new List<FrameworkElement>();
int pageNumber = 0;
var printDate = DateTime.Now;
var size = A4Size;
var currentPage = new Report(size, printDate);
currentPage.Render();
var listElements = new Queue<ElementsToPrint>(...);
var dummyRenderer = new Viewbox();
dummyRenderer.Child = currentPage;
dummyRenderer.Measure(InfiniteSize);
dummyRenderer.Arrange(new Rect(dummyRenderer.DesiredSize));
dummyRenderer.UpdateLayout();
var template = (DataTemplate)View.FindResource("ItemTemplate");
dummyRenderer.Child = null;
var availableHeight = currentPage.View.ActualHeight;
while (listElements.Count > 0)
{
var elementToRender = listElements.Dequeue();
dummyRenderer.Child = new ListViewItem()
{
Content = elementToRender,
ContentTemplate = template,
Foreground = Brushes.Black
};
dummyRenderer.Measure(InfiniteSize);
dummyRenderer.Arrange(new Rect(dummyRenderer.DesiredSize));
dummyRenderer.UpdateLayout();
var renderedItem = (ListViewItem)dummyRenderer.Child;
dummyRenderer.Child = null;
var willItFit = availableHeight > renderedItem.ActualHeight;
if (willItFit)
{
currentPage.DataListView.Items.Add(renderedItem);
availableHeight -= renderedItem.ActualHeight;
}
else
{
dummyRenderer.Child = currentPage;
dummyRenderer.Measure(InfiniteSize);
dummyRenderer.Arrange(new Rect(dummyRenderer.DesiredSize));
dummyRenderer.UpdateLayout();
dummyRenderer.Child = null;
pages.Add(currentPage);
// Set up a new Page
pageNumber++;
currentPage = new DiaryReport(size,pageNumber,printDate,anonymous);
dummyRenderer.Child = currentPage;
dummyRenderer.Measure(InfiniteSize);
dummyRenderer.Arrange(new Rect(dummyRenderer.DesiredSize));
dummyRenderer.UpdateLayout();
dummyRenderer.Child = null;
availableHeight = currentPage.DataListView.ActualHeight;
currentPage.DataListView.Items.Add(renderedItem);
availableHeight -= renderedItem.ActualHeight;
}