Loading search results in a new form - c#

I have been working on trying to understand ArrayList but I have run into a problem with the final part of my search function.
I have an array list set up to take data in from a StreamReader. The data consists of numerous properties to do with teams, such as their name and the image path to their logo.
I have then created a search that scans through the array list for a specific piece of string input through a textbox by the user.
I have then created an if statement to open up a new form if that search was returned true.
I would like the new form to load up each property of the team according to the data searched for. E.g if I searched for "Liverpool" it would then come up with the manager name, stadium name as well as the searched for name in the new form. I do not know how to do this.
The only tool that I can really think of to do this is the load.event procedure but I can not find a lot of information about linking it to an array list.
private void btn_Search_Click(object sender, EventArgs e)
{
foreach (Object obj in allTeams)
{
Team = (Team)obj;
if (team.teamName.ToUpper() == nameToMatch.ToUpper()) //case insensitive search.
{
FormTeam frmTeam = new FormTeam(Team); //windows form that displays team info.
frmTeam.Visible = true;
break;
}
}
}
above is my search function. (I have not used List<T> because it was required that everything must be stored in an ArrayList.)
Is what I am trying to achieve possible? And if so how?

Also, you may want to use Linq on your ArrayList
foreach(var team in allTeams.OfType<Team>())
{
if(team.TeamName.Equals(nameToMatch, StringComparison.InvariantCultureIgnoreCase))
{
frmTeam = new FormTeam(Team);
Aplication.Run(frmTeam); // or frmTeam.Show();
break;
}
}
Inside the Constructor of your TeamForm class you simply assign all Values from the Team- Object to the fields on the Form.
public FormTeam (Team team)
{
teamName.Text = team.TeamName; // label or something
teamPlayerCount.text = team.PlayerCount.ToString();
...
}

If you need to search on a string such as the teamName, it would be better to use something like a Dictionary<string,Team> rather than an Arraylist. Then you'd be able to do
Team t = dic[nameToMatch.ToUpper()];
where dic is the instance of Dictionary<string,Team> that contains all your teams.

First, you're missing a variable name there. I think you meant
foreach (Object obj in allTeams)
{
Team t = (Team)obj;
if (t.teamName.ToUpper() == nameToMatch.ToUpper()) //case insensitive search.
{
FormTeam frmTeam = new FormTeam(t); //windows form that displays team info.
frmTeam.Visible = true;
break;
}
}
But why not used a typed generic List, not have to do all this silly casting.
But your question is "how can I pass what I searched to the new form", correct? I'd change the constructor for FormTeam to something like FormTeam(Team t, string nameToMatch) and save the value locally in TeamForm so you can do highlighting or whatever.

Related

ASP.NET C# Adding LinkButtons to a List

I'm building an ASPX web page where some links will be visible or invisible depending on the user's access level. My thought was rather than create multiple functions and turn each link on or off, I could keep things neat and tidy by making List<LinkButton> members, like:
private List<LinkButton> adminButtons = new List<LinkButton>();
private List<LinkButton> guestButtons = new List<LinkButton>();
private List<LinkButton> userButtons = new List<LinkButton>();
Then I'd call one function to make them all visible or invisible.
private void DisplayButtons(List<LinkButton> linkButtons, bool displayButtons) {
for (int i = 0; i < linkButtons.Count; i++) {
linkButtons[i].Visible = displayButtons;
}
}
But I hit two snags. Firstly, I couldn't figure out how to initialize the lists with the links. For example, I've got asp:LinkButtons with IDs like ID='Link_UserManagement', ID='Link_InventoryManagement', et cetera. I can do this in the ASPX.CS file, and it works:
Link_UserManagement.Visible = false;
Link_InventoryManagement.Visble = true;
But this doesn't work:
private List<LinkButton> adminButtons = new List<LinkButton>() { Link_UserManagement }
And then if I try adding them this way, then the List count increases, but the values are null:
adminButtons.Add(Link_UserManagement);
So obviously I don't understand something about how these links work. My question is, why isn't this working the way I thought it would?
Secondly, if there's a better way to go about hiding and showing content based on a user's access level, I'm open to suggestions.

Int field in Winform does not update null values in SQL Server database using C#

In my Winforms C# application, I have fields with Int data type and they are set to accept null values in SQL Server database (allow nulls).
In the forms I have some textboxes which are bound to those int data type fields. If I don't enter anything while creating a new record, it accepts. If I enter a number in the textbox, it also accepts it, and then if I delete it, it doesn’t accept it anymore and even doesn't allow me to move to the next field.
If I set its value as null or "" through code, it simply ignores and does not even update changes which I made in other non int text fields.
I am using following method to update.
this.Validate();
this.itemsbindingSource.EndEdit();
this.tableAdapterManager.UpdateAll(this.sBSDBDataSet);
What can I do for the textbox to accept null values?
I have tried following.
IDTextBox.Text = "";
IDTextBox.Text = null;
I have tried following with the help of above solutions (specially Mr. Ivan) and this is how it worked out.
To clear the int field on the form:
IDTextBox.Text = String.Empty;
Then on Designer.cs file of the form, as suggested by Mr. Ivan, I searched for 'IDtextbox.DataBindings.Add' and replaced
this.IDTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.itemsbindingSource, "PictureID", true));
with
this.IDTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.itemsbindingSource, "PictureID", true, System.Windows.Forms.DataSourceUpdateMode.OnValidation, ""));
It took me a whole day to search and finally I posted my problem here, and it got solved in 1 hour.
This seems to be one of the WF data binding bugs. I can't say what exactly is causing it, but in order to make it work one should set Binding.NullValue property to "" (empty string, the default is null).
I couldn't find a way to do that in the designer, and also it would be quite annoying to locate all text boxes needed. So I would suggest you the following quick-and-dirty approach. Create a helper method like this:
public static class ControlExtensions
{
public static void FixTextBoxBindings(this Control control)
{
if (control is TextBox)
{
foreach (Binding binding in control.DataBindings)
if (binding.NullValue == null) binding.NullValue = "";
}
foreach (Control child in control.Controls)
child.FixTextBoxBindings();
}
}
and then simply include the following in your form Load event:
this.FixTextBoxBindings();
TextBox dont accept null value.
You can check if it null and set String.Empty;
If(dbValue == null)
{
IDTextBox.Text = String.Empty;
}
else
{
// here set value to your textbox
}

Keeping track of 40+ control values

I am in need of some guidance for the following design.
I have a tab control that contains various group boxes. Within the group box, there are specific controls that relates to that group box. For example:
Now whenever a change is made to any control in the group box, the value for the control needs to be tracked because at the end of the application run cycle, the control data will need to be saved to a file that contains that value. An example file is:
HOT_STANDBY_FEATURE_ENABLE [val from control here]
HEART_BEAT_DIGITAL_OUTPUT [val from control here]
....
A design that I have in mind has another that has just properties that the group box form sets whenever a ValueChanged event occurs on a control.
Example code:
class ConfigurationValues
{
public int HotStandbyValue { get; set; }
public int HeartBeatDigitalOutputValue { get; set; }
//...add all other controls here
}
The downside that I see to this is that there are 40 controls on that tab page, so I'd have to manually type each property. When the file needs to be generated at the end of the application run cycle, I have a method that gets the value of the control need.
Example:
private void GenerateFile()
{
string[] file =
"HOT_STANDBY_FEATURE_ENABLE " + ConfigurationTabSettings.HotStandbyValue;
}
Another design consideration I need to make is that whenever a user clicks "Open Configuration File", the values from the file from disk need to be loaded into the properties so the form can take that data on startup and populate the controls within the group boxes with their respective values.
Any suggestions on this design would be greatly appreciated. I know this is not the most efficent way to do this and am not the most experienced programmer, so any Google keywords I can search for would be great also.
You could xml serialise and xml deserialise your ConfigurationValues class rather than writing manual "generate file" and "read file" methods
http://support.microsoft.com/kb/815813
You'll need to bind the controls Text or Value properties to the properties in your ConfigurationValues class e.g.
ConfigurationValues cv = Repository.ReadConfigValues();
numPulseFilterDelay.DataBindings.Add("Value", cv, "PulseFilterDelay");
// Add the rest of your control bindings here
on the btnSave_Click() of your Form, end the current edit on the form and save the config values
void btnSave_Click(object sender, EventArgs e)
{
BindingContext[cv].EndCurrentEdit(); // Commits all values to the underlying data source
Repository.SaveConfigValues(cv);
}
In your repository class you'll need methods to Load() and Save() the data. You can put XmlSerialization code in here, or write your own format (depending on your requirements)
public class Repository
{
public static ConfigurationValues LoadConfigValues()
{
var cv = new ConfigurationValues();
string[] lines = File.ReadAllLines("values.cfg");
foreach (string cfg in lines)
{
string[] nameValue = cfg.Split(new char[] { ' ' } ); // To get label/value
if (nameValue[0] == "HOT_STANDBY_FEATURE_ENABLE")
cv.HotStandbyFeatureEnable = nameValue[1];
else if (nameValue[0] == "SOME_OTHER_PROPERTY")
cv.SomeOtherProperty = nameValue[2];
// Continue for all properties
}
return cv;
}
public static void SaveConfigValues(ConfigurationValues cv)
{
var builder = new StringBuilder();
builder.AppendFormat("HOST_STANDBY_FEATURE_ENABLE {0}\r\n", cv.HostStandbyFeatureEnable);
// Add the rest of your properties
File.WriteAllText("values.cfg", builder.ToString());
}
}

select items from listview

What i'm trying to do is select an item in my listview, and it works! That is it works once, the first time a select an item it go's well, the second time a get an argument out of range exception on features[0].SubItems[1].Text; on the zero.
this is what i have:
private void listViewFeatures_SelectedIndexChanged(object sender, EventArgs e)
{
ListView.SelectedListViewItemCollection features = listViewFeatures.SelectedItems;
string feature = features[0].SubItems[1].Text;
BL_AddReport addReport = new BL_AddReport(this.databaseConnectionString);
Dictionary<string, bool> pictures = addReport.GetpicturesFromFeature(feature);
foreach (KeyValuePair<string, bool> pic in pictures)
{
if (pic.Value) {
pictureBoxCar.Image = Image.FromFile(pic.Key);
}
else
{
pictureBoxEquip.Image = Image.FromFile(pic.Key);
}
}
}
Does anyone know what the problem is?
I'm betting you'd get this exception if you clicked off of the listview as well.
Remember that this event is for selection changes.. which may mean that something was selected and now nothing is. In fact, according to this an event is fired once for every thing that is selected. Take a look at that link for more information and designs around this problem if that is the case for you.
Otherwise just check to make sure that your "features" variable has anything inside of it before indexing into it

Correct way to implement web part personalisation for listboxes

Trying to work out this whole web part personalisation, and trying to implement it for a list box.
Well the end result will be two list boxes, with interchangeable values (ie, a value will only exist in one of the listboxes)
But I can't maintain the datasource for it. So maybe I'm going about it wrong?
This is what I have for a test H2 tag on the page
[Personalizable(PersonalizationScope.User)]
public string LabelText {
get { return h2Test.InnerText; }
set { h2Test.InnerText = value; }
}
And it works fine, if I have a textbox and use it to change the value of LabelText, then when I close the browser it automagically persists the change.
So I thought, ok, then maybe the same will work with a list box
[Personalizable(PersonalizationScope.User)]
public DomainList Domains {
get { return (DomainList)lstBxDomains.DataSource; }
set {
lstBxDomains.DataSource = value;
lstBxDomains.DataBind();
}
}
Where DomainList is just a class which extends List, and Domain is just a three field class, int, string, string.
But it doesn't, so is this too complicated for the webpart personalisation automagican, or have i just implement it wrongly (Which is more than likely)
This is my event handler to remove the items from the list:
protected void btnRemDomain_Click(object sender, EventArgs e) {
if (IsPostBack && lstBxDomains.SelectedIndex > -1) {
for (int i = 0; i < lstBxDomains.Items.Count; i++) {
if (lstBxDomains.Items[i].Selected) {
Domains.Remove(Domains.Find(d => d.ID.ToString() == lstBxDomains.Items[i].Value));
}
}
Domains = Domains;
}
}
The Domains=Domains; line is in there to see if explicitly setting the value made a difference (as Removing doesn't acutally reset the value of the field), but it doesn't. I've also tried creating a new local DomainList setting it to the global one, and then doing the remove/find on it, and then setting the local one to the global. But not working either.
I have managed to resolve this by using WebPart.SetPersonalizationDirty(this); in the set accessor of Domains, but would someone mind confirming if this is an appropriate way to do it?

Categories

Resources