C# Monotouch/Xamarin - Replace Entire Tab Button With Image In UITabBarController - c#

Is it possible to replace the entire tab button for each tab with a different image in the UITabBarController?
INSTEAD OF THIS - (Standard Default Tab Controller Appearance)
DO THIS - (Custom Tab Controller Appearance Using Images)
How would I go about doing this?
Customization of the UITabBarController seems pretty nasty. You can change the tint colour, but that affects the colour of the tab image in it's various selected/not-selected states....

It's not obvious. But here's how to use full colored images and optionally omit the text label.
var tabBarItem = new UITabBarItem("Item Text", null, 1);
tabBarItem.SetFinishedImages(UIImage.FromBundle("./Images/addexpense.png"), UIImage.FromBundle("./Images/addexpense.png"));
var controllerToAdd = new UIViewController()
{
TabBarItem = tabBarItem
};
tabBarController.SetViewControllers(new UIViewController[]
{
controllerToAdd
};
The result can then look something like this (of course you can also get rid of the text completely by omitting the "Item Text" shown in my example):

Related

Resizing and Collapsing label in winforms

first time poster, sorry if something isn't as it should be.
I'm new to Winforms and am trying to build a simple application that will display multiple features of an item (like Size, Composition, etc.). Each Characteristic has a Name, can have a Descritpion, and some can have sub-characteristics (having also a name and sometimes a descritpion).
I want to display them one under the other, with the Name of the feature on a blue background that span the whole width of the container, with the description underneath. The name will be (or have) a button (or similar) that when clicked collapse or expand the description. This must be created at run time because I don't know how many feature an object has until the user generate it.
The issues I'm running in are that either I can't span the blue background the whole width of the container (if using a FlowLayoutPanel), or I have some issue with the Description text being not the right size (either it wraps but is too big, or it doesn't wrap and then I can't see the whole text).
Some things are fixed, mainly the number of main sections (like Size, Composition, Weather, etc.), so I can prepare the skeleton before runtime.
The closest i've been to making it work gives this. This issue here is that the height of the Panel which the description label is embded in is fixed, and if I put in in Autosize, the text don't show (probably because the label is in Fill dock style). Just as information, this is what it looks like when collapsed (this is indeed what I'm looking for)
I know some library exists with collapsible panels, but I'd rather try to make it work without external libraries. Thanks in advance for any help !
This is the code that produces the results in the screenshots :
Panel SizeDescrPanel = new Panel();
SizeDescrPanel.Dock = DockStyle.Top;
//SizeDescrPanel.AutoSize = true;
SizeDescrPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
SizeDescrPanel.BackColor = Color.Bisque;
SizePanel.Controls.Add(SizeDescrPanel);
Label SizeDescrLbl = new Label();
SizeDescrLbl.Text = Lorem;
SizeDescrLbl.AutoSize = false;
SizeDescrLbl.Dock = DockStyle.Fill;
SizeDescrLbl.BackColor = Color.BurlyWood;
SizeDescrPanel.Controls.Add(SizeDescrLbl);
/*using(Graphics g = CreateGraphics())
{
SizeF size = g.MeasureString(SizeDescrLbl.Text, SizeDescrLbl.Font, SizePanel.Width);
SizeDescrPanel.Height = (int) Math.Ceiling(size.Height);
}*/
Panel SizeNamePanel = new Panel();
SizeNamePanel.Dock = DockStyle.Top;
SizeNamePanel.BackColor = Color.Cyan;
SizeNamePanel.AutoSize = true;
SizePanel.Controls.Add(SizeNamePanel);
Button SizeNameBtn = new Button();
SizeNameBtn.Text = "<Size Name> ..." + SizeDescrLbl.Height;
SizeNameBtn.TextAlign = ContentAlignment.MiddleLeft;
SizeNameBtn.FlatStyle = FlatStyle.Flat;
SizeNameBtn.AutoSize = true;
SizeNamePanel.Controls.Add(SizeNameBtn);
SizeNameBtn.Click += delegate { HideShowPanel(SizeDescrPanel); };
It,s a test project, so later I'll put that in different methods. What isn't shown here :
I have a main panel set to Fill containing everything.
The text "SIZE" is a label set to Top
Under it is another Panel (SizePanel) that is set to Top and Autosize is at True. This is the Panel inside which I'm puttin my size name and my size description. If I had a subfeature, it would be included (ideally) inside descritpion with the same configuration (button expanding/collapsing the descritpion of the SubFeature)

Drop Down Menu in c# (position and use)

For my project in school, I have to create a window and program that has a menu, and for the menu, I need to have a drop down menu.
The drop down menu works and all, however, I cannot seem to get it to go into the lower part of my window.
Here is my code:
var MenuWindow = new Form();
MenuWindow.Height = 300;
MenuWindow.Width = 300;
MenuWindow.Text = "Menu";
ToolBarButton Numbers = new ToolBarButton("Number of players");
ToolBar DropDownMenu = new ToolBar();
MenuItem menuItem1 = new MenuItem("1");
MenuItem menuItem2 = new MenuItem("2");
ContextMenu ContentsOfMenu = new ContextMenu(new MenuItem[] { menuItem1, menuItem2 });
DropDownMenu.Buttons.Add(Numbers);
Numbers.Style = ToolBarButtonStyle.DropDownButton;
Numbers.DropDownMenu = ContentsOfMenu;
DropDownMenu.Left = 95;
DropDownMenu.Top = 215;
DropDownMenu.Width = 100;
DropDownMenu.Height = 10;
MenuWindow.Controls.Add(DropDownMenu);
MenuWindow.Show();
As you can see I have tried to add the Height, Width, Left and Top coordinates. However, this has done no difference to where the position of this drop down menu.
I have used a ToolBar and a ToolStrip and the result is the same; I cannot move the position of the button/drop down menu.
Also if you have any suggestions on how to improve my code, please do as I am new to this part of c#.
The first thing to consider is that the name of your variable "DropDownMenu" is misleading. That variable is a ToolBar, not a drop down menu. When you're actually selecting from the drop down on your form, the control you are using is "Numbers". "Numbers" is really what should be called "DropDownMenu".
Given this, I suspect the reason you can't change the Top and Left properties of your toolbar is because it is in fact a toolbar. Toolbars just go at the extremes of their containers. It never makes sense to put them in the middle. It's odd that they even have this property, but I'm guessing that it's because they inherit from "Control". The rendering engine must simply ignore these properties. If you really must have this, take a look at Hans Passant's comment under your question.
I don't work too much with Windows Forms Controls, but I do recall that typically you're more likely to want "ComboBox" for this. And put the combo box straight on your form, bypassing any toolbars. Like this:
var label =
new Label() {
Text = "Players",
Top = 20,
Left = 20,
Width = 75
};
var combo =
new ComboBox() {
Left = label.Left + label.Width,
Top = label.Top,
Width = 150,
Height = 10
};
combo.Items.Add("1");
combo.Items.Add("2");
var MenuWindow =
new Form() {
Height = 100,
Width = 300,
Text = "Menu"
};
MenuWindow.Controls.Add(combo);
MenuWindow.Controls.Add(label);
MenuWindow.Show();
Also, since you're new, note the different style. It's not particularly better, but it's worth knowing about. Setting properties in this manner helps me block things together better. Also, it's generally okay to use the "var" keyword when it's painfully obvious what kind of variable you have. So, for instance, it is very clear that combo is a ComboBox. Consequently I just use "var". When it's even a little unclear, then write out the actual type.

RichTextBox showing with plain text when added to Panel

I have a custom Tabs Control I created. It works as a coloured Label for the tab itself and as a Panel to hold the contents. My application reads UI parameters from config files. Take this line as an example from the controls config:
RTFBOX=(ID - rtf1) (BOUNDS - 0,0,100,100) (MULTILINE - enable) (FILE - email_rules.rtf)
This line tells the application to create an instance of my custom RichTextBoxPlus class and the important thing to take from this is that it is set up to read rich text from the FILE parameter. If I don't add this RichTextBoxPlus to another Control it shows it's rich text formatting absolutely fine.
I have another config that reads actions at runtime, this can be simple stuff like telling a Button created with the controls config that when it is clicked, it should fire off an email using content from a TextBox control. I have an action that pairs controls to each tab in the Tabs custom control. For example:
ADDTOTABS=(OBJECT - tabsControl1) (CONTROLS - panel1, panel2)
This finds tabsControl1 and adds panel1 to the 1st tab and panel2 to the 2nd tab. In this example, Panels are being added to each tab instead of individual controls as the Panels could hold multiple controls, handled at runtime through the ADDTOPANEL action.
ADDTOPANEL=(OBJECT - rtf1) (TARGET - panel1) (TRIGGER - onload)
So the rtf1 instance of RichTextBoxPlus is added to panel1 which is then added to the respective Panel of the Tabs control's 1st tab.
What I have found is rtf1 displays with rich text formatting absolutely fine if added to panel1 but not adding panel1 to Tabs.
The ADDTOTABS action executes this method:
private void TabContents_Action(Tabs tabpanel, string[] ctrls)
{
string[] tabs = tabpanel.GetTabNames();
for(int i = 0; i < tabs.Length; i++)
{
Control control = this.Controls.Find(ctrls[i], true).FirstOrDefault();
tabpanel.SetTaggedObject(control, tabs[i]);
}
tabpanel.SetTabActive(tabs[0]);
}
The SetTaggedObject method of the Tabs class finds the Panel control that corresponds with the tab name provided:
public void SetTaggedObject(Control ctrl, string tab)
{
Control container = this.Controls.Find(tab, false).FirstOrDefault();
container.Controls.Add(ctrl);
}
Doesn't seem to be anything untoward about this method.
The SetTabActive method of the Tabs class has a little more bulk. This handles changing the appearance of all tabs so that inactive tabs look different to the active tab. It is also hides and shows the panels for each tab based on whether the tab is active.
public void SetTabActive(string tab)
{
LabelPlus activeTab = this.tabs.Find(x => x.Name.Equals(tab));
List<LabelPlus> inactiveTabs = new List<LabelPlus>(this.tabs.FindAll(x => !x.Name.Equals(tab)));
activeTab.BackColor = this.ActiveColor;
activeTab.ForeColor = this.ActiveForeColor;
string panelName = tab.Remove(tab.Length - this.tabSuffix.Length);
Panel activeTabPanel = (Panel)this.Controls.Find(panelName, true).FirstOrDefault();
activeTabPanel.Bounds = new Rectangle(
new Point(this.tabStart, this.originalLocation.Y + this.TabTotalHeight), this.Size);
ControlCollection activeTabCtrls = activeTabPanel.Controls;
foreach(LabelPlus inactiveTab in inactiveTabs)
{
inactiveTab.BackColor = this.InactiveColor;
inactiveTab.ForeColor = this.InactiveForeColor;
string inactivePanelName = inactiveTab.Name.Remove(inactiveTab.Name.Length - this.tabSuffix.Length);
Panel inactiveTabPanel = (Panel)this.Controls.Find(inactivePanelName, true).FirstOrDefault();//
inactiveTabPanel.Bounds = new Rectangle(
new Point(this.tabStart, this.originalLocation.Y + this.TabTotalHeight), this.Size);
ControlCollection inactiveTabControls = inactiveTabPanel.Controls
foreach (Control ctrl in inactiveTabControls) { ctrl.Location = new Point(0, ctrl.Location.Y); ctrl.Hide(); }
}
foreach (Control ctrl in activeTabCtrls)
{ ctrl.Location = new Point(0, ctrl.Location.Y); ctrl.Show(); }
}
Not sure but I'd say the issue must be in this method. Any thoughts?

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?

TabControl tab buttons location

I'm looking for solution for my problem. I want to change location for tabcontrol's TabButtons or add control assigned to tabpage but outside TabControl. TabPages are added dynamically. Example:
Form1___________ _ [] X
_______________________
Some TabPage content
Tab1 | Tab2 | Tab3 | < >
TextBox assigned to Tab's
________________________
So if I change tabs by clicking on Tab1,Tab2,Tab3 TabPage + TextBox content should change depending on Tab. The first idea was to put TabButtons on bottom and add ArrayList what contains TextBox content, catch TabControl change tab event and change TextBox content, but there was an issue with editing and adding that content. In few words: I wan't to put TabButtons between 2 controls(for example between two textboxes).Do you have any ideas?
If I understand what you're asking for... You want when you click on a tab, it controls two different things? Like two different text boxes?
If that is true, you should be able to do it like this.
foreach (thing in your ArrayList)
{
TabPage tabPage = new TabPage("Name of tab"); // Add a new tab page
RichTextBox rtb = new System.Windows.Forms.RichTextBox();//RTF box
TextBox tb = new System.Windows.Forms.TextBox(); //Text box
//Set up size, position and properties
rtb.LoadFile("some/Path/to/a/file");
//set up size, position of properties
tb.Text = "Some text I want to display";
tabPage.Controls.Add(rtb); //Add both boxes to that tab
tabPage.Controls.Add(tb);
tabControl1.TabPages.Add(tabPage); //Add that page to the tab control
}
Only thing you should have to mess around with is the layout. And make sure to have the tabControl added with the designer.
you can create your own textbox class which inherits from textbox class :
class MyOwnTextBox:TextBox
{
public int parent_tab;
}
So you can add your textbox by assigning a parent_tab id to them . so in tab button click event , you can do something like that :
foreach(MyOwnTextBox txt in this.Controls)
{
if(txt.parent_tab==1) txt.visible=false;
}
You could also place the tabs on the left or the right side of your tab control. That is not perfect, but would come closer to your idea than placing them above or below the tab control.
You can add a new tab page dynamically like this
tabControl1.TabPages.Add("My new Tab");
I'm not sure I understand exactly what your trying to do. If you want to change the tab from another object, just use:
TabController.SelectTab(0);
If you want to remove a TabPage and add it to another, use:
TabController.Controls.Remove(TabPage1);
TabController2.Controls.Add(TabPage1);
Edit: From further read, I think you want something like this:
this.TabController.ControlAdded += AddLinksToBottomOfTabs;
public void mainSettingsTabController_ControlAdded(object sender, ControlEventArgs e)
{
//Create label with e.Control.Name as the title and
//add it to wherever you want it added.
}

Categories