Want to add Controls at Runtime in IPhone Application C#, Monotouch - c#

I have a TabViewController. It consists of several views. For a particular view I want to add some buttons dynamically at runtime. The view already have some controls which has been created using Interface Builder.

You can add controls like this:
// create new control
var control = new UIView(); // or UIButton, etc.
// set control props ..
control.Hidden = false;
control.Frame = x // = Bounds
// ...
// add control to parent
window.AddSubview(control);

just sample code for UIButton
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(aMethod:) forControlEvents:UIControlEventTouchDown];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[yourView addSubview:button];
Here you can set Button Type/Controlling Event/Title etc as per your requirement.
Hope this helps.

Related

Getting list of checked radiobuttons in .net

TLDR; Looking for a method to retrieve all radiobuttons by means of something like this... (psudo)
List<RadioButton> btn = new List<RadioButton>;
btn = stackPanel.getAllRadioButtons()
I am currently building a little quiz application in C#. I have functions that add the required GUI elements to a groupbox. I would like to know if there is any way that I can loop through the created elements (for instance radio buttons) to see which are checked.
Here is one of the functions along with how they are added to the window.
private void tfQ(string questionBody)
{
StackPanel questionPanel = new StackPanel{Orientation = Orientation.Vertical};
questionPanel.Children.Add(new Label { Content = questionBody });
GroupBox group = new GroupBox();
RadioButton trueRadio = new RadioButton();
trueRadio.Content = "True";
RadioButton falseRadio = new RadioButton();
falseRadio.Content = "False";
questionPanel.Children.Add(trueRadio);
questionPanel.Children.Add(falseRadio);
group.Content = questionPanel;
mainStack.Children.Add(group);
}
Constructor:
public quiz()
{
tfQ("This is a true/false question");
Window w = new Window();
w.Content = mainStack;
w.Show();
}
I have found many ways to do it in the C# scripting format
(using the Control function ...)
var checkedButton = container.Controls.OfType<RadioButton>()
.FirstOrDefault(r => r.Checked);
but I have not yet found a "programmatic" way of doing it. I have considered changing the type of void tfQ to a StackPanel, but that only helps me to easier loop through the stack panels, althought that only partly solves me problem - allows me to easier loop through the StackPanels but I still don't know how to get the RadioButtons on a panel.
P.S I am very new to C# - with experience in Java/C/C++/Python
I made use of the following code to cast the content into a new groupbox and stackpanel, respectively.
if (child is GroupBox)
{
if ((child as GroupBox).Content is StackPanel)
{
StackPanel d = (StackPanel)((GroupBox)child).Content;
}
}
This allowed me to cast the content into a local copy of a control. It may not be the best way - I'm sure it is very inefficient to be honest. Solved the problem.

How do I add UI Children to an empty WPF-Page?

I'm having a MainWindow which is a NavigationWindow. Inside this MainWindow I want to switch in several Pages. One of the Pages has to be dynamically generated by Code, not by XAML. When I had a normal window before, I could add UI components like this:
Button b = new Button();
b.Content = "Hello";
this.AddChild(b);
Or if I added (for example) a StackPanel with this method first, I could add Children to this StackPanel with:
myPanel.Children.Add(b);
However, the Page Class doesn't have a Children Attribute or a AddChild Method.
The only method I found so far is:
AddVisualChild(b);
The page shows but I don't see any components which I added with this method.
So how do I add Children to a WPF-Page correctly?
First of all, the Window.AddChild will throw an exception when you add more than one object to it, because Window is a ContentControl. Page allowes only 1 child .So you set the child using the Page.Content property. So you want to add a container to your Page and then add children to the container.
For example:
Button b = new Button();
b.Content = "Hello";
StackPanel myPanel = new StackPanel();
myPanel.Children.Add(b);
this.Content = myPanel;
I'm not really sure if this works for you but you could try to set the content of a page to a user control. E.g. use a StackPanel and add all the children to it. After that you set the content of the Page to the Stackpanel.
Here is an lazy example in the constructor of a MainWindow.
public MainWindow()
{
InitializeComponent();
StackPanel panel = new StackPanel();
Button b1 = new Button {Content = "Hello"};
Button b2 = new Button {Content = "Hi"};
panel.Children.Add(b1);
panel.Children.Add(b2);
Page page = new Page {Content = panel};
this.Content = page;
}

How can I pass a parameter to control event handler?

I am creating a winforms app which generates a number of panels at runtime. I want each panel, when clicked, to open a web link.
The panels are generated at runtime:
for (int i = 0; i < meetings.Count(); i++) {
Panel door = new Panel();
door.Location = new System.Drawing.Point((i * 146) + (i * 10) + 10, 10);
door.Size = new System.Drawing.Size(146, 300);
door.BackgroundImage = ConferenceToolkit.Properties.Resources.Door;
door.Click += new EventHandler(door_Click);
Controls.Add(door);
}
and I want the event handler to point to a URL that is stored somehow in the Panel attributes. (On a web form I could use Attributes["myAttribute"] but this doesn't seem to work with WinForms):
private void door_Click(object sender, EventArgs e)
{
Panel p = sender as Panel;
Process.Start(p.Attributes["url"]);
}
There are many options for this, you may store URL in the (unused in Panel) Text property:
door.Text = FindUrl(meetings[i]);
Used like:
Process.Start(p.Text);
As alternative you may use general purpose Tag property:
door.Tag = FindUrl(meetings[i]);
With:
Process.Start(p.Tag.ToString());
Tag property is usually right place for these things and, becauase it's of type object, you can even use it to store complex types (in case you need more than a simple string).
See also similar posts for slightly more complex cases: this, this and this.
You can store the URL that you want in the Panel's Tag propertie
for example
p.Tag = "www.google.com";
and then you can use it when use cast the Panel in the on click method
reference for the .Tag property
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.tag(v=vs.110).aspx

Using MonoTouch.Dialog and XibFree together

I have been using MT.D for some time now to make table-based UI layouts. However, I have found that XibFree is awesome for laying out custom pages while keeping the layout code as code (rather than using a designer). This is for (a) easy customization through code and (b) maintainability by other developers.
I would like to use both at the same time. XibFree's table creation isn't as easy to use as MT.D but I can't find a way to extract a UIView from a section and place it into my XibFree layout (all I need is a UIView to do this).
Any ideas? I've tried using the View from the DVC, and the TableView from the RootElement, but no luck with getting either to display in my layout.
Example:
new NativeView()
{
// table view from RootElement - shows empty space where table should be
View = entryView.TableView
},
I've also tried adding a UITableView to my view, and setting the TableView property of the DVC to that, with a call to ReloadData(), with no success.
I was able to get it to load this way:
var re = new RootElement ("") {
new Section("Please Sign In")
{
(userName = new EntryElement("User name", "Your user name", "")),
(password = new EntryElement("Password", "Your password", "", true))
}
};
var entryView = new DialogViewController (re, false);
//entryView.
var uitv = new UITableView (RectangleF.Empty, UITableViewStyle.Grouped);
entryView.LoadView ();
//entryView.TableView = uitv;
re.TableView.Frame = RectangleF.Empty;
uitv = re.TableView;
Then in my layout:
new NativeView()
{
View = uitv,
LayoutParameters = new LayoutParameters()
{
Width = AutoSize.FillParent,
Height = 200
}
},
Which gives me a scrollable region inside the view:
The region with the lines is its own scrollable view, which I did not expect given I was just giving the area the table view from the one section I created. I want to take the sections out of it and insert them into my view, so there is no scrollable view inside my view. (Never mind the weird look of the UITextfields, I'm using Pixate to style stuff.)
I hope it's just something small I am missing here and that this should be a trivial task.
EDIT: Is there also a way to calculate the height for the rendered section, to give to the LayoutParameters object?

UIBarButtonItem with Custom View

I try to create a UIBarButtonItem with a custom view for a Toolbar. The view itself is displayed well, but when i click the BarButton, no action occurs. It looks like the touch event is not forwarded from the view to the UIBarButtonItem instance. I have checked the responder chain and i think it looks good. I have also searched the internet and checked the Apple documentation, but can't find any hint for my problem.
Here is my code:
g__objWeatherButton = new UIBarButtonItem[1];
UIView l__objCustomView = g__objWeatherDisplay.InfoBarButton; // Returns a reference to my custom view
UIBarButtonItem l__objButton = new UIBarButtonItem(l__objCustomView);
l__objButton.Clicked += delegate {this.WeatherButtonEvent();}; // my action handler
l__objButton.Width = 200;
l__objButton.Enabled = true;
g__objWeatherButton[0] = l__objButton;
this.Items = g__objWeatherButton; // "this" is my UIToolbar object
Can someone give me a hint where the problem is? Or a working code sample (in c# please - have found some examples in Objective-C, but apparently overlooked the crucial trick ;-)
No special trick. When you want to add a custom view to a toolbar or navigation bar, you should subscribe (and respond) to that view's events. So instead of using a UIView to hold your image, create a UIButton with UIButtonType.Custom and subscribe to that button's TouchUpInside event.
You then initialize it like you do with the UIView:
UIButton l__objCustomUIButton = UIButton.FromType(UIButtonType.Custom);
//l__objCustomUIButton.SetImage(UIImage.FromFile("your button image"), UIControlState.Normal);
l__objCustomUIButton.TouchUpInside += delegate { this.WeatherButtonEvent(); };
UIBarButtonItem l__objButton = new UIBarButtonItem(l__objCustomUIButton);
Just make sure you declare the button in the class scope.
Although the answer put me in the right direction I still had trouble displaying the button. Only after I added the following the was button display with image.
l__objCustomUIButton.Frame = new System.Drawing.RectangleF(0, 0, 40, 40);
Regards
Paul
There is an easier way and the custom button will now react like a regular toolbar button.
this.SetToolbarItems( new UIBarButtonItem[] {
new UIBarButtonItem(UIBarButtonSystemItem.Refresh, (s,e) => {
Console.WriteLine("Refresh clicked");
})
, new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace) { Width = 50 }
, new UIBarButtonItem(UIImage.FromBundle
("wrench_support_white.png"), UIBarButtonItemStyle.Plain, (sender,args) => {
Console.WriteLine("Support clicked");
})
}, false);

Categories