Get the "Text" value out of "System.EventArgs objArgs" - c#

As you can see in that screenshot in "objArgs" there is a property "Text". How can I reach that property?

You need to cast the args to ToolBarItemEventArgs, at which point you can access the ToolBarButton it refers to:
var toolBarArgs = (ToolBarItemEventArgs) objArgs;
switch (toolBarArgs.ToolBarButton.Text)
{
...
}
However, I would suggest not switching on the text. Instead, ideally set up a different event handler for each of your buttons. If you really can't do that, you can use:
var toolBarArgs = (ToolBarItemEventArgs) objArgs;
var button = toolBarArgs.ToolBarButton;
if (button == saveButton)
{
...
}
Or you could switch on the Name rather than the Text - I'd expect the Name to be basically an implementation detail, whereas the Text is user-facing and could well be localized.

Related

How to change the default button label "No Preference" in FormFlow

Is there a way to modify the default "No Preference" label of the button when updating the user inputs to read e.g. "I don't want to change anything." without introducing a new Resources.*.resx file?
I tried all templates that allow changing such literals but I found no one that could achieve this. TemplateUsage.NoPreference can be used to change only the value of an optional field, not the button label.
You can do it by overriding the Template value in your FormFlow.
Here is an example based on the Microsoft.Bot.Sample.SimpleSandwichBot:
public static IForm<SandwichOrder> BuildForm()
{
var formBuilder = new FormBuilder<SandwichOrder>()
.Message("Welcome to the simple sandwich order bot!");
var noPreferenceStrings = new string[] { "Nothing" };
// Set the new "no Preference" value
formBuilder.Configuration.Templates.Single(t => t.Usage == TemplateUsage.NoPreference).Patterns = noPreferenceStrings;
// Change this one to help detection of what you typed/selected
formBuilder.Configuration.NoPreference = noPreferenceStrings;
return formBuilder.Build();
}
Demo capture:

Accessing components of another form

I have two Forms in my application. A Form has the following fields: txtPower, txtTension and txtCurrent. I would like to access the values ​​filled in these TextBox through another Form. In the second Form I instantiated an object of the first Form (MotorForm), however I do not have access to the TextBox.
public MacroForm()
{
InitializeComponent();
MotorForm motorForm = new MotorForm();
motorForm.Show();
}
Is there any way?
Please do not expose the controls in your form. Never. (Unless you have a really good reason.)
If the problem is simple enough not to use MVVM (or the like) in your program (which you should consider for every program that's but trivial), you should expose the values of the instantiated form via properties. Think
public string Power
{
get { return txtPower.Text; }
set
{
if(ValidatePower(value))
{
txtPower.Text = value;
}
else
{
// throw ??
}
}
}
If we can make a sensible assumption about the type of the value we could extend this to
public double Power
{
get
{
// parse the value
// validate the value
// throw if not valid ??
// return the value
}
set
{
// validate the value
// set the value in the text box
}
}
If you exposed the txtPower object, you'd make the instantiating class depend on implementation details of the instantiated class, which is virtually never a good thing.
It seems that your problem is a perfect situation for using ShowDialog for opening your form.
To accomplish this, you need to change the Modifiers property of the controls you want to access on MotorForm and set them to Public. And also set the DialogResult property of your form somewhere to a desired value i.e OK. Anyway the easier way to do this is to set it on the button that is supposed to close the form. Suppose OK or CANCEL buttons.
Then you can create your form this way:
MotorForm motorForm = new MotorForm();
if(motorForm.ShowDialog() == DialogResult.OK)
{
string myValue = motorForm.txtPower.Text; //you can access your values this way
}

button over button

I have a problem in my winform c# project.
In my project I have two main functions, one makes buttons at run time and the other function allows me to move the button on the form at run time. Now what can I do if I have button on other button so I made function that replace the button places as it was at the beginning but the function make problems if someone can help me it will be great!
public void upandunder(Button cBtn1, Button cBtn2)
{
if ((cBtn1.Location.X == cBtn2.Location.X) && (cBtn1.Location.Y == cBtn2.Location.Y))
{
int placex = cBtn1.Location.X;
int placey = cBtn1.Location.Y;
cBtn1.Location.X = cBtn2.Location.Y;
cBtn1.Location.Y = cBtn2.Location.Y;
cBtn2.Location.X = placex;
cBtn2.Location.Y = placey;
}
}
its makes me that errorError 1 Cannot modify the return value of 'System.Windows.Forms.Control.Location' because it is not a variable
Correct, the return value of the Location property is not editable. According to the documentation:
Because the Point class is a value type (Structure in Visual Basic, struct in Visual C#), it is returned by value, meaning accessing the property returns a copy of the upper-left point of the control. So, adjusting the X or Y properties of the Point returned from this property will not affect the Left, Right, Top, or Bottom property values of the control. To adjust these properties set each property value individually, or set the Location property with a new Point.
Therefore, you need to rewrite your code to the following:
(Also, I strongly recommend naming the parameters something other than x and y, since you're dealing with coordinates that have x and y values within the function...)
public void upandunder(Button btn1, Button btn2)
{
if ((btn1.Location.X == btn2.Location.X) && (btn1.Location.Y == btn2.Location.Y))
{
Point originalLocation = btn1.Location;
btn1.Location = btn2.Location;
btn2.Location = originalLocation;
}
}
or even better, just compare the two Point values as returned by the Location property (the Point structure overloads the == operator):
public void upandunder(Button btn1, Button btn2)
{
if (btn1.Location == btn2.Location)
{
Point originalLocation = btn1.Location;
btn1.Location = btn2.Location;
btn2.Location = originalLocation;
}
}
Of course, I fail to see how that accomplishes anything. First you check to see that the buttons are positioned on top of each other (have exactly the same x- and y-coordinates), and then if they do, you swap their positions. They're already in the same positions—you tested that before you executed the swapping code.
Judging by the name of your function (upandunder, which should be UpAndUnder following standard .NET naming conventions), it seems as if you wish to change the Z order of the buttons. If that's the case, then you should call either the BringToFront or SendToBack methods of the button control.
The Location Property on a Control returns a Point. The Point structure has the X and Y values you're working with. Instead of accessing them directly, I think you want to provide new Location points.
Give this a try (It works on my Machine)
public void UpAndUnder(Button cBtn1, Button cBtn2)
{
if (cBtn1.Location == cBtn2.Location.Y)
{
Point oldPoint = new Point(cBtn1.Location.X, cBtn1.Location.Y);
cBtn1.Location = new Point(cBtn2.Location.X, cBtn2.Location.Y);
cBtn2.Location = oldPoint;
}
}
If you want to place one button over other, just call
button1.BringToFront();
this will change Z-order of button1 and place it over all other controls.

Why does MonoTouch.Dialog use public fields for some Element options, and public properties for others

I am trying to get a StringElement's 'Value' to update in the UI when I set it after already setting up the DVC.
e.g:
public partial class TestDialog : DialogViewController
{
public TestDialog() : base (UITableViewStyle.Grouped, null)
{
var stringElement = new StringElement("Hola");
stringElement.Value = "0 Taps";
int tapCount = 0;
stringElement.Tapped += () => stringElement.Value = ++tapCount + " Taps";
Root = new RootElement("TestDialog")
{
new Section("First Section")
{
stringElement,
},
};
}
}
However the StringElement.Value is just a public field, and is only written to the UICell during initialization when Element.GetCell is called.
Why isn't it a property, with logic in the setter to update the UICell (like the majority of Elements, e.g. EntryElement.Value):
public string Value
{
get { return val; }
set
{
val = value;
if (entry != null)
entry.Text = value;
}
}
EDIT :
I made my own version of StringElement, derived from Element (basically just copied the source code from here verbatim)
I then changed it to take a class scoped reference to the cell created in GetCell, rather than function scoped. Then changed the Value field to a property:
public string Value
{
get { return val; }
set
{
val = value;
if (cell != null)
{
// (The below is copied direct from GetCell)
// The check is needed because the cell might have been recycled.
if (cell.DetailTextLabel != null)
cell.DetailTextLabel.Text = Value == null ? "" : Value;
}
}
}
It works in initial testing. However I am not sure on whether taking a reference to the cell is allowed, none of the other elements seem to do it (they only take references to control's placed within the cells). Is it possible that multiple 'live'* cell's are created based on the one MonoTouch.Dialog.Element instance?
*I say live to indicate cells currently part of the active UI. I did notice when navigating back to the dialog from a child dialog the GetCell method is invoked again and a new cell created based on the Element, but this is still a 1-1 between the element and the live cell.
For the main question:
Why does MonoTouch.Dialog use public fields for some Element options, and public properties for others?
I've been through the code, and I don't think there's a consistent reason for use of either.
The Dialog project was not part of the MonoTouch project initially - I don't think Miguel knew how useful it was going to turn out when he started wrote and grew it - I think he was more focussed on writing other apps like TweetStation at the time.
I know of several people (including me!) who have branched the code and adapted it for their purposes. I would guess at some future point Xamarin might write a 2.0 version with stricter coding standards.
Taking references to live cells
For limited use you can do this... but in general don't.
The idea of the table view is that cells get reused when the user scrolls up and down - especially in order to save memory and ui resources. Because of this is a long list, multiple elements might get references to the same cell.
If you do want to cache a cell reference then you probably should override GetCell() so that it never tries to reuse existing cells (never calls DequeueReusableCell)
Alternatively, you could try to change some code in the base Element class in order to find out if the Element has a current attached cell - this is what CurrentAttachedCell does in my branch of Dialog https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross.Dialog/Dialog/Elements/Element.cs (but that branch has other added functions and dependencies so you probably won't want to use it for this current work!)

Image name as string, use it to make image visible WPF with C#

I have an image name as a string. The real imagename on the form is called "image". So i get something like this:
image.Visibility = Visibility.Hidden;
string imageName = "image";
// need something here to make it usable...
changedImageName.Visibility = Visibility.Visible;
Now, a string can not be used in combination with the Visibility property.
I cant really find what i must make the string to, to make it usable for the visibility property.
If i see this page: http://msdn.microsoft.com/en-us/library/system.windows.visibility.aspx
Do I understand correct that I make it a "enum" ? And if yes, how do I get a string to that property?
EDIT 1
I see I have not been explaining it proper enough.
I forgot to mention I am using a WPF form.
on this form, I have put an image.
In the initialize part, the image get set to hidden.
so for example the imagename I named "Image"
so I use image.Visibility = Visibility.Hidden;
later on in my code, I want to make the image visible again, depending on what the user does.
so, instead if just using the name to get the image visible again, I want to use a string.
this string is looking exactly as the name of the image.
but i cant use the string in combination with the Visibility function.
but i cant find anywhere what i must make this string to, to be able to use that visibility option on it.
hope i explained a bit better now :).
Later on, i will have multiple images on the WPF window.
So the key is that i will use the string, that is corresponding with the name of the image.
Depending on what the user has input into the string, some image will or will not show.
EDIT 2
If you have:
String theName = ImageName.name
you can get the name of the image into a string, so you can do stuff with it.
i am looking for a way to do the exact opposite of this. So i want to go from a string, to that name, so after that i can use this to control the image again.
Edit 3
some example:
private void theButton_Click(object sender, RoutedEventArgs e)
{
//get the Name property of the button
Button b = sender as Button;
string s = b.Name;
MessageBox.Show("this is the name of the clicked button: " + s);
//the name of the image to unhide, is the exact same as the button, only with IM in front so:
string IM = "IM";
IM += s;
MessageBox.Show("this string, is now indentical to the name of the image i want to unhide, so this string now looks like: " + IM );
// now, this wont work, because i cant use a string for this, although the string value looks exactly like the image .name property
// so string IM = IMtheButton
// the image to unhide is named: IMtheButton.name
IM.Visibility = Visibility.Visible;
}
looks like you're using WPF, so you can create a boolean to visibility converter and use it with a boolean (and create a method that receives string if necessary) and just use:
<ContentControl Visibility="{Binding Path=IsControlVisible, Converter={StaticResource BooleanToVisibilityConverter}}"></ContentControl>
or any other converter...
check this links:
http://bembengarifin.wordpress.com/2009/08/12/setting-visibility-of-wpf-control-through-binding/
http://andu-goes-west.blogspot.com/2009/05/wpf-boolean-to-visibility-converter.html
http://msdn.microsoft.com/en-us/library/system.windows.controls.booleantovisibilityconverter.aspx
EDIT 1:
so then you will have to iterate over the images and check if your string is equals to name of the Image class.
something like this (not tested):
foreach (Image img in container.Items)
{
if img.Name == yourMagicallyString;
{
img.Visibility = Visibility.Visible;
}
else
{
img.Visibility = Visibility.Hidden;
}
}
If I understand correctly, you are trying to find a control based on the name or ID of the control. If so, try this:
Control changedImage = this.Controls.Find("image", false)[0];
Depending on what you are targeting and what version you might need to tweak a little
EDIT Updated per #Alexander Galkin comments about Find returning an array. There should definitely be some checking and whatnot but I'm leaving that up to the OP.
EDIT 2 For finding a control by name in WPF see this post.
The code I was looking for:
object item = FindName(IM);
Image test1 = (Image)item;
test1.Visibility = Visibility.Visible;

Categories

Resources