I need to create and add some TextBoxes which has same attribute as some other TextBoxes.
Is there a way to copy the attributes to another ?
I'm looking for a one like solution. I know I can set variable one by one.
TextBox Old = new TextBox() {
Size = new System.Drawing.Size(25,25),
Location = new Point(a.row*25, a.col*25),
Multiline = true
};
TextBox New = new TextBox(); //which has same location,size as old one ?
EDIT The TextBox might be any other .NET controls !
You can use this Solution. You can write a extention and that get via Reflection all propertys
Please use the search function in future.
Create an initializer method:
private void InitializeTextBox(TextBox textBox)
{
textBox.Size = new System.Drawing.Size(25, 25);
textBox.Location = new Point(a.row * 25, a.col * 25);
textBox.Multiline = true;
}
And use like this:
TextBox t1 = new TextBox(), t2 = new TextBox();
InitializeTextBox(t1);
InitializeTextBox(t2);
Or a copier method:
private void CopyTextBoxProps(TextBox source, TextBox dest)
{
dest.Size = source.Size;
dest.Location = source.Location;
dest.Multiline = source.Multiline;
//...
}
and use it accordingly.
Probably the most straightforward way is this:
TextBox New = new TextBox {
Size = Old.Size,
Location = Old.Location,
Multiline = Old.Multiline
};
If this is something you need to do a lot, you could write an extension method that does the same thing:
public static class TextBoxExtensions {
public static TextBox Copy(this TextBox textBoxToCopy) {
var copiedTextBox = new TextBox {
copiedTextBox = textBoxToCopy.Size,
copiedTextBox = textBoxToCopy.Location,
copiedTextBox = textBoxToCopy.Multiline
};
}
}
Usage:
var copyOfOld = Old.Copy();
If you are going to add a lot more properties to copy, I'd think about using AutoMapper and defining a map between TextBox and TextBox. If you're interested in that path, let me know and I'll post a sample.
It would turn this into a one liner, but you'd need a dependency on AutoMapper, but it's available on NuGet: http://nuget.org/packages/AutoMapper/2.2.0
First, take a dependency on AutoMapper.
Define the mapping somewhere in your project:
Mapper.CreateMap<TextBox, TextBox>();
Usage:
var newTextBox = Mapper.Map<TextBox, TextBox>(Old);
or, if you already have an instance you want to stuff it into:
Mapper.Map(Old, newTextBox);
AFAIK, there is no built in, one line solution, so it's either the extension method, or take a dependency on AutoMapper. The extension method does not have to do it that way, you can use reflection or other choices there.
I use AutoMapper in just about all of my projects and it's invaluable.
You can define many mappings in your map definition, then all your copies become one liners. Well, besides the definition :)
Related
I got a hidden form (ViewRegisterForm) which has a ListView. This form is hidden, but I want to update the ListView from another form (RegistrationForm) during runtime.
To be honest I am not sure what is the best method to approach this scenario hence I am open to suggestions..
private void UpdateListView(string value){
ViewRegisterForm.MdiParent = this;
ViewRegisterForm.Show();
ViewRegisterForm.Location = new Point(10, 5);
}
Obviously this did not work!
The issue you have is the following:
You are trying to reference the class directly without making into an actual object.
Create the object first, and set it to the form type
ViewRegisterForm VRF = new ViewRegisterForm();
Now you will deal with this Object instead of the class itself.
Use VRF.PublicObjectInThisForm to call them
Here is the full example using your code.
In C#:
<!-- language: c# -->
private void UpdateListView(string value)
{
ViewRegisterForm VRF = new ViewRegisterForm();
VRF.MdiParent = this;
VRF.Show();
VRF.Location = new Point(10, 5);
}
In Vb.Net:
<!-- language: vb.net -->
Private Sub UpdateListView(ByVal value As String)
Dim VRF As ViewRegisterForm = New ViewRegisterForm()
VRF.MdiParent = Me
VRF.Show()
VRF.Location = New Point(10, 5)
End Sub
How do i create a new Button/Canvas with a dynamic name?
Button {buttonname read from text file} = new Button;
I have googled this for a while now but i can't find the solution.
Thank you!
I'm not sure if I understood correctly, but that name in your example is not the button name, it's just the reference name used in code to access the button. The button name would be set like this:
buttonRefName.Name = "ButtonName1";
So you can set the name to whatever you want: dynamically generated names inside a loop, names read from a file, etc...
You can use the same reference name for multiple buttons, just be sure to add it to List or to WPF Window, Panel, etc... before creating the new one:
var buttonList = new List<Button>();
var buttonRef = new Button { Name = "YourButtonName" };
buttonList.Add(buttonRef);
buttonRef = new Button { Name = "YourButtonName2" };
buttonList.Add(buttonRef);
It not possible the way you want to do it. If you are reading from a text file better use a List or better a Dictionary... an example use is as follows:
var buttons = new Dictionary<string, Button>();
buttons["yourName"] = new Button();
// logic goes here
I have a project to which I delegate the function of creating a library of (static)? classes used in all my other projects. It is referenced via solution in these cases.
For instance, I have an extension which creates checkboxes within a given GroupBox's panel, and that works great:
public static void PreencheCheckboxesPanel(this Panel p, List<CheckBox> listaCheckBoxs) {
var count = 0;
listaCheckBoxs.ForEach(
i => {
i.Location = new Point(10, 10 + ((count) * 25)); //"dynamic" and not-so-effective resizing here
i.AutoSize = true;
count++;
});
p.Controls.AddRange(listaCheckBoxs.ToArray());
}}
Problem is, I need to insert a static checkbox on the top of the list, which will receive a method to (un)?check all the checkboxes below.
So my code will become
internal static CheckBox CKB_ancora = new CheckBox(){};
public static void PreencheCheckboxesPanel(this Panel p, List<CheckBox> listaCheckBoxs) {
var count = 0;
if (adicionaAncora) {
CKB_ancora.Text = textoAncora;
CKB_ancora.CheckedChanged += (sender, args) => {
ChecaCheckBoxes(p, CKB_ancora.Checked);
};
listaCheckBoxs.Insert(0, CKB_ancora);
}
listaCheckBoxs.ForEach(
i => {
i.Location = new Point(10, 10 + ((count) * 25)); //"dynamic" and not-so-effective resizing here
i.AutoSize = true;
count++;
});
p.Controls.AddRange(listaCheckBoxs.ToArray());
}}
where ChecaCheckBoxes is another
public static void ChecaCheckBoxes(this Panel b, bool checkStatus = true) {
var listaCheckBoxs = (from Control c in b.Controls where c is CheckBox select (CheckBox)c).ToList();
listaCheckBoxs.ForEach(
i => {
i.Checked = checkStatus;
});
}
and CKB_ancora needs to be a solution-wide recognized object.
The reason? I have another extension named GetSelectedCheckBoxes which will be used to return all the checked ... ah... checkboxes within the groupbox. And, in order to make sure that the "anchor" (I call it like this, since I don't have a name to a (un)?check-all checkbox) won't be returned as well.
If I run this code, it will compile, but... will run accross an InvalidOperationException at Application.SetCompatibleTextRenderingDefault, right at Main(); Apparently, a control cannot be created/instantied before this method is run at mainpoint, which is the exact definition of "static".
Question: Knowing that I NEED a way to keep this particular check solution-wide visible... How do I do it?
Unfortunately, you have not provided a good, minimal, complete code example, and lacking enough context it is very hard to provide good, specific advice.
That said, it seems that somewhere in this static class of yours, you have a field named CKB_ancora, and you are probably initializing it using a field initializer, possibly like this:
private CheckBox CKB_ancora = new Checkbox();
And having done this, you are finding that when the class is initialized (typically on the first time something in the class is accessed at runtime), that happens too soon and an exception is thrown.
Assuming that's correct, then it seems to me that most obvious and simplest "fix" is to initialize the object lazily. For example:
private Lazy<CheckBox> _ckb_ancora =
new Lazy<CheckBox>(() => new CheckBox());
private CheckBox CKB_ancora { get { return _ckb_ancora.Value; } }
That will wrap the object storage in a property, which in turn uses an instance of Lazy<T> to defer initialization until the first time any code actually tries to access it.
Now, that said, I'm not very enamored of your approach here, with a static member that is used in some instantiated object. What if someone using your library wants to use the code with two or more Panel instances? A Control (including a CheckBox) can't be a child of more than one other Control at a time, so having a single static instance of the Control is just not going to work.
IMHO, it would probably be better to instead use some identifying feature such as the Name or Tag property of the CheckBox to handle the control appropriately (e.g. such as filtering it out of enumerations).
For example:
public static void PreencheCheckboxesPanel(this Panel p, List<CheckBox> listaCheckBoxs) {
var count = 0;
if (adicionaAncora) {
CheckBox CKB_ancora = new CheckBox();
CKB_ancora.Text = textoAncora;
CKB_ancora.Name = "CKB_ancora";
CKB_ancora.CheckedChanged += (sender, args) => {
ChecaCheckBoxes(p, CKB_ancora.Checked);
};
listaCheckBoxs.Insert(0, CKB_ancora);
}
listaCheckBoxs.ForEach(
i => {
i.Location = new Point(10, 10 + ((count) * 25)); //"dynamic" and not-so-effective resizing here
i.AutoSize = true;
count++;
});
p.Controls.AddRange(listaCheckBoxs.ToArray());
}}
And, for example:
public static void ChecaCheckBoxes(this Panel b, bool checkStatus = true) {
var listaCheckBoxs = b.Controls
.OfType<CheckBox>().Where(c => c.Name != "CKB_ancora").ToList();
listaCheckBoxs.ForEach(
i => {
i.Checked = checkStatus;
});
}
That way, when you go to retrieve the list of CheckBox controls, the special one you added at the beginning is ignored.
Even with that, I think the code is still pretty fragile. The above would work better, but IMHO it would probably be even better if you weren't using static members for all of this in the first place. I.e. instead you should design some mechanism that allows you to relate an instance of the helper class to the Panel object it's helping with, so that you can in fact initialize and store per-instance information, without running into problems of order of execution, as well as of limitations of use of the code with just a single client.
Without a better code example, I don't see any good way to offer any specific advice along those lines though.
I have a series of lists in a static class (used as a global class)
public static class globalClass
{
public static List<classA> aList = new List<classA>();
public static List<classB> bList = new List<classB>();
public static List<classC> cList = new List<classC>();
}
I want to generate a xaml button for each list, and was told reflection was a bad idea. This is how I handled it using reflection.
//get FieldInfo for globalClass
TypeInfo typeInfo = IntrospectionExtensions.GetTypeInfo(typeof(globalClass));
IEnumerable<FieldInfo> FieldInfoList = typeInfo.DeclaredFields;
foreach (FieldInfo f in FieldInfoList)
{
//Only look at lists
if(f.FieldType.ToString().StartsWith("System.Collections.Generic.List`1")){
StackPanel s = new StackPanel();
s.Orientation = Orientation.Horizontal;
TextBlock textBlock = new TextBlock();
textBlock.FontSize = 45;
textBlock.Text = f.Name.ToString();
Button addButton = new Button();
addButton.Click += delegate(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(addObjectToLibraryPage), f);
};
addButton.Margin = new Thickness(10);
addButton.Name = "addButton";
addButton.Content = "add";
Button deleteButton = new Button();
deleteButton.Click += delegate(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof(deleteObjectFromLibraryPage), f);
};
deleteButton.Margin = new Thickness(10);
deleteButton.Name = "deleteButton";
deleteButton.Content = "delete";
s.Children.Add(addButton);
s.Children.Add(deleteButton);
//add new textBlock and stackpanel to existing xaml
stackPanel.Items.Add(textBlock);
stackPanel.Items.Add(s);
}
}
Is there any cleaner way to do this? Hopefully I would like to be able to pass the actual list instead of a FieldInfo.
I don't want to have to handle each list individually because I may end up with 20+ lists and am using them all in a very similar way.
An example of what I am trying to do:
Suppose I have a grocery/nutrition App, and I want users to be able to record what they eat/need from the store. They can select from a list of Fruit, Vegetables, Meat, Dairy, Sweets, Canned Goods, Etc..
But, I want them to be able to (as an advanced option) be able to edit the list of possible fruits, or any other food category. And I don't want to just have a list of "food" because meat will record things like minimum cooking temperature or something like that.
So, under advanced options, I would want two buttons for each category (add to fruit, delete from fruit). And theoretically add an Import/Export page so I can share my list of fruits with other people or something.
It doesn't seem like the answers pointing to using a superclass will work. See: C# polymorphism simple question
You can create a list to contain all the existing lists you have. You can then iterate over the list to create the buttons. If you wish to maintain a label for each list you could use a dictionary with the key as the label text and list as the value.
The proposed solution aside, do take into account the comments given from Sayse.
sorry for confusing title.
I am using a thirdparty contorl for Spreads and it has a comboBoxCellType().
In my code there are like 20 places that I have a code like this:
ComboBoxCellType cbo = new ComboBoxCellType()
cbo.OtherStuff...
now I want all the occurences of such codes to have an extra property called listwidth =0; so
something like:
ComboBoxCellType cbo = new ComboBoxCellType()
cbo.listwidth=0;
cbo.OtherStuff
one way is just to search the code and add it manually. but I was wondering is there a better way using Inheritance and overriding to do this?
You can create a static class that can be used to new up the ComboBoxCellType.
Something like this:
public static class ComboBoxCellTypeFactory
{
public static ComboBoxCellType Create()
{
return new ComboBoxCellType(){listwidth = 0};
}
}
With this you can new up ComboBoxCellType instances with the listwidth property set to 0 like this:
ComboBoxCellType cbo = ComboBoxCellTypeFactory.Create();
cbo.OtherStuff...
Encapsulate the creation and initialization of a ComboBoxCellType to a method and call that method from every place you previously did this.
In general, if you find yourself repeating code, see if you could extract the code into a method that you can call. Keep your code DRY.
Something like:
private ComboBoxCellType BuildComboBoxCellType()
{
ComboBoxCellType cbo = new ComboBoxCellType()
cbo.listwidth=0;
cbo.OtherStuff...
return cbo;
}
And in your original code:
ComboBoxCellType cbo = BuildComboBoxCellType();
If you have access to the source code I would suggest placing a this.listwidth = 0 in the constructor of your ComboBoxCellType.