eternal question about twoForms:
frm02 frm02 = new frm02();
frm02.Text = "Objects";
ds02 = new DataSet();
ds02.ReadXml(path02);
frm02.dgv02.DataSource = ds02.Tables[0]; //error: dgv02 is inaccessible...
frm02.ShowDialog();
pleaseHelp!
You need to make dgv02 public. By default, when you add types via the designer, they are not public. You can edit their properties in the design window, and change the accessibility level to public.
That being said, a better option might be to create a public property that returns the appropriate control, or, even better, allows you to set the data. For example, if you add this method to your form:
public void SetDatasource(DataSet data)
{
this.dgv02.DataSource = data;
}
You could then call this as:
frm02.SetDatasource(ds02);
Related
In WPF, writing
<TextBlock x:Name="foo"/>
will make the control public. To make it private, one must explicitly specify the FieldModifier:
<TextBlock x:Name="foo" x:FieldModifier="private"/>
I find this strange. I don't think it is a good coding style to access a subcontrol directly from outside the class. For example, I would avoid writing
var muc = new MyUserControl();
muc.foo.Text = "foo";
Instead I would write a public method and use it:
public void SetFooText(string text) { foo.Text = text; }
// in somewhere else
var muc = new MyUserControl();
muc.SetFooText("foo");
or write a public property
public string FooText
{
get { return foo.Text; }
set { foo.Text = value; }
}
// in somewhere else
var muc = new MyUserControl();
muc.FooText = "foo";
So, I don't really see any advantages setting controls to public by default. Maybe it would be safer if private is the default, like everything in C#.
Why is public the default?
Edit:
Well, I made a mistake. The default is internal as others have mentioned. But the question why it is not private is still waiting for an answer.
Default value of the x:FieldModifier for C# is NotPublic(Internal)
TypeAttributes.NotPublic is the default behavior because it is infrequent that code outside the assembly that compiled the XAML needs access to a XAML-created element. WPF security architecture together with XAML compilation behavior will not declare fields that store element instances as public, unless you specifically set the x:FieldModifier to allow public access.
As we see if they were private by default assembly which compiled the XAML would not have access to it XAML-created element.
You can find more information here MSDN
If I have the following code:
Button[] _buttonarray = new Button[40]; // it is outside any function (situated in the public partial class MainWindow : Window)
And a new created button in a function called
private void createbutton()
{
_buttonarray[b]=new Button();
_buttonarray[b].Content = "Content";
...
}
How Can I edit _buttonarray[b] content from another function like,
private void editbutton()
{
_buttonarray[b].Content = "New Content";
}
Note: variable b is outside so it can be change from any function.
Make it Static:
public static Button[] ButtonArray = new ..
and use MainWindow.ButtonArray to access it.
Worth pointing out that by doing that, it is shared throughout every instance of your MainWindow.
Edit:
Just to point out - rather than saying 'outside' it is more common to use the definition of Scope , simply put - if you can access something A from somewhere B,then A is in B's Scope.
Also - read more regarding static here: Static and instance fields
If you want to edit a specifically created button, you can keep that button in a designated field, which is in both the creation code's scope and the alteration code's scope:
var myButton = new Button(){Content="Content"};
_buttonarray[b]=myButton;
SomethingInCommon.SpecificButton = myButton;
and the access it elsewhere that have access to SomethingInCommon.
Keep SpecificButton value until you don't need it any longer.
You're editing a button with the code you have, it's just that it's probably not the one you're expecting because the index of b has likely been iterated. Just access the right index, possibly by using Find and a predicate on Content to make sure you're editing the right button.
Let me just preface this with: I Googled high and low for this, and found many examples and solutions, and I still can't figure this out.
In a .aspx.cs code behind file, I have the following:
NewsArticleList listall = NewsArticleManager.GetListAll();
foreach (NewsArticle x in listall)
{
Control c1 = (NewsArticleContainer)LoadControl("~/UserControls/NewsArticleContainer.ascx");
((NewsArticleContainer)c1).PopulateWithNewsArticle(x);
mynewspanel.Controls.Add(c1);
}
I have a method in the User Control called PopulateWithNewsArticle() that accepts a NewsArticle, and populates the User Control's web controls accordingly:
public void PopulateWithNewsArticles(NewsArticle x)
{
lbltitle.Text = x.Title;
lblcategory.Text = x.Category;
//...etc.
}
Now this works, this is fine. But what I would like to learn/understand, is how I can pass the NewsArticle x to the User Control when I LoadControl(), so that upon creation of the User Control, I can unpackage the NewsArticle on the User Control's Page_Load, and set the web control properties from right when the User Control is instantiated as opposed to doing it after instantiation with the PopulateWithNewsArticle method (like I have it now).
Our you can expose public property NewsArticle in the NewsArticleContainer.ascx, so you will have initialization code like this:
var control = (NewsArticleContainer)LoadControl("~/UserControls/NewsArticleContainer.ascx");
control.NewsArticle = x;
You could use
Control c1 =
(NewsArticleContainer)LoadControl(typeof(NewsArticleContainer),new object[]{ x });
This one is an overloaded of Page.LoadControl(), It has this syntax
public Control LoadControl(
Type t,
Object[] parameters
)
After that you would have to create a valid constructor for your UserControl too, which could be something like this
class NewsArticleContainer:System.Web.UI.UserControl
{
public NewsArticleContainer(NewsArticle x)
{
// Some cool code stuff here
}
}
For more on this go here.
in my Win Forms app I create an array of dynamic custom controls inside a loop. These, lets call them 'boxes', are like my basic pieces of information. I also create string arrays in other parts of the code that contain the information of this 'boxes', so that for example string[3] is a variable of box[3] and so does stringa[3], stringb[3], stringc[3]... all the arrays with the same index are related to the box with that index. Hope I make myself clear.
Only 2 of this strings are shown in 2 labels inside each custom control 'box' in the array, but the others are there because I want to make something so that when the user clicks one of these controls the other strings can be shown in another control. Sort of something like "More Information...". All the 'boxes' in the array need to have the same event handler because I create +100.
To put it more into context, each custom control 'box' in the array shows the Symbol and the Price of a stock and I want that when the user clicks on each stock more quote information is shown on another special control which is like a placeholder for "More info".
I am thinking of 2 ways to do it:
If I could "detect" the index of the clicked control (which is the same in the strings related to it), I could just set this to an int j and all I have to do is show all the strings a,b,c... with index j. Unfortunately I cannot find a way to do this, maybe it is not even possible.
The other way I have thought is to create some properties for my custom control which "store" this variables, and in my app instead of assigning strings I would set properties for each control, which I could later retrieve when the control is clicked. I haven't tryed this because I don't know exactly how to do it.
What do you think? Do you know how can I achieve this or do you have a different idea that will work? Please help! Thanks in advance.
It's kind of a broad implementation question since there are countless ways you could implement something like this.
If you are creating two collections, one with the buttons and one with the information, you potentially could just assign each of the buttons 'Tag' properties to point to the corresponding info and assign a generic OnClick event handler that displays the info.. something like:
infoControl.text = ((InfoClass)((Button)Sender.Tag)).pieceOfInformation;
But again there are many ways to do this, and the choice comes down to how you store your information.
For your first method, you could have a property of your custom control that is the index.
public class Box : Control
{
// ...existing code
private int index;
public int Index
{
get
{
return index;
}
set
{
index = value;
}
}
}
OR
For your second method, you could have a property of your custom control that is the additional info string.
public class Box : Control
{
// ...existing code
private string extraInfo;
public string ExtraInfo
{
get
{
return extraInfo;
}
set
{
extraInfo = value;
}
}
}
In either case, you could then access the proper information right in your click handler for the "box".
i don't know about the first way - got to noodle around more, but in the second way you can extended your custom or built-in control: for example:
public class ExtendedLabel: Label
{
public string[] MoreInfo { get; set; }
}
and initialize it
public TestForm()
{
InitializeComponent();
ExtendedLabel label = new ExtendedLabel();
label.MoreInfo = new string[] { "test" };
this.Controls.Add(label);
label.AutoSize = true;
label.Location = new System.Drawing.Point(120, 87);
label.Name = "label1";
label.Size = new System.Drawing.Size(35, 13);
label.TabIndex = 0;
label.Text = label.MoreInfo[0];
}
And later in your event handler you can use the inside information
I have a winforms application.
I have a textbox on one form (call F1) and when a button is clicked on this form (call F2), it launches another form.
On F2, I want to set a string via a textbox (and save it to a variable in the class), and then when I close this form, the string will appear in a label in F1.
So I am basically sharing variables between both forms. However, I can't get this to work correctly. How would this code look?
I would add a new property to form2. Say it's for a phone number. Then I'd add a friend property m_phone() as string to form 2. After showing an instance of form2 but before closing it, you can refer to the property m_phone in form1's code.
It's an additional level of indirection from Matthew Abbott's solution. It doesn't expose form2 UI controls to form1.
EDIT
e.g.:
public string StoredText
{
get;
private set;
}
inside the set you can refer to your UI control, like return textBox1.text. Use the get to set the textbox value from an earlier load.
And:
public string GetSomeValue()
{
var form = new F2();
form.ShowDialog();
return form.StoredText;
}
Just ensure that StoredText is populated (or not, if appropriate) before the form is closed.
Are you showing the second form as a dialog, this is probably the best way to do it. If you can avoid doing shared variables, you could do the following:
public string GetSomeValue()
{
var form = new F2();
form.ShowDialog();
return form.TextBox1.Text;
}
And called in code:
Label1.Text = GetSomeValue();
This might not be the most efficient way of approaching, but you could create a class called DB (database). Inside this class, create variables like
public static bool test or public static bool[] test = new bool[5];
In your other forms, you can just create an instance. DB db = new DB(); then grab the information using db.test = true/false. This is what I've been doing and it works great.
Sorry, I'm only like a year late.