Object reference not set to an instance of an object during xml serialization and problem with selection of combobox item upon loading - wpf

question 1. I have this issue of "Object reference not set to an instance of an object" when my Majorlabel is empty and this occurs after i try to do a save button click on xml serialization. How can i fix this?
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
string savepath;
SaveFileDialog DialogSave = new SaveFileDialog();
// Default file extension
DialogSave.DefaultExt = "txt";
// Available file extensions
DialogSave.Filter = "XML file (*.xml)|*.xml|All files (*.*)|*.*";
// Adds a extension if the user does not
DialogSave.AddExtension = true;
// Restores the selected directory, next time
DialogSave.RestoreDirectory = true;
// Dialog title
DialogSave.Title = "Where do you want to save the file?";
// Startup directory
DialogSave.InitialDirectory = #"C:/";
DialogSave.ShowDialog();
savepath = DialogSave.FileName;
DialogSave.Dispose();
DialogSave = null;
FormSaving abc = new FormSaving();
if (!string.IsNullOrEmpty(MajorversionresultLabel.Content.ToString()))
{
abc.Majorversion = MajorversionresultLabel.Content.ToString();
}
abc.Startzbuildfrom = StartzbuildcomboBox.SelectedItem.ToString();
using (Stream savestream = new FileStream(savepath, FileMode.Create))
{
XmlSerializer serializer = new XmlSerializer(typeof(FormSaving));
serializer.Serialize(savestream, abc);
}
}
As recommended,
here is the line of error:
if (!string.IsNullOrEmpty(MajorversionresultLabel.Content.ToString()))
{
abc.Majorversion = MajorversionresultLabel.Content.ToString();
}
Question 2. I used this line to save my combo box selection:
abc.Startzbuildfrom = StartzbuildcomboBox.SelectedItem.ToString();
and in my load i have this line:
StartzbuildcomboBox.SelectedItem = abc.Startzbuildfrom
why wont it select the combobox selection previously?

As a first note, I'd recommend only putting one question into a single query here. Makes it easier.
For your second question, my guess is that you're running into a reference variable problem. I think that calling the ToString() method on the SelectedItem actually creates an entirely new string variable. Then, when you try to set the selected item later, it can't find the new string as a possible item to select because, even though the two strings have the same value, they are different objects. I would maybe recommend that you either:
1) Set the selected item by searching through your combo box contents to find a string whose value matches the one you've saved
or
2) Save the actual reference by saying abc.Startzbuildfrom = StartzbuildcomboBox.SelectedItem. Then set the selected item from that reference.

I suspect that MajorversionresultLabel is null, or MajorversionresultLabel.Content is null. Thus your statement
if (!string.IsNullOrEmpty(MajorversionresultLabel.Content.ToString()))
will throw a NullReferenceException. Try this instead:
if (MajorversionresultLabel != null && MajorversionresultLabel.Content != null && MajorversionLabel.Content.ToString() != string.Empty)
I bet your NullReferenceException will go away.

Related

Using a variable to name an Event Handler

Updated 10 Nov 2022
I have the following code in a Winforms program:
void CreateCheckBoxes(Control parentControl, int left, int top, int lineSpace)
{
List<string> listVariables = new List<string>() { "AllowColumnReorder", "CaptureFocusClick", "ColScaleMode", "ColumnTracking", "RowTracking", "EnsureVisible", "FullRowSelect", "GridLines", "HideSelection", "HoverSelection", "IsFocused", "LabelEdit", "MultiSelect", "Scrollable", "VisualStyles" };
foreach (string varName in listVariables)
{
CheckBox ctlTemp = new CheckBox { Name = "chk" + varName, Text = varName, Top = top, Left = left };
parentControl.Controls.Add(ctlTemp);
top += lineSpace;
}
chkAllowColumnReorder.CheckedChanged += new EventHandler(chkAllowColumnReorder_CheckedChanged);
// The name 'chkAllowColumnReorder' does not exist in the current context
}
It works to the extent that I can create as many CheckBoxes as I like based on the length of listVariables. However, I want the name of the CheckedChanged event handler to be based on the name of the control.
As well as my original question I now find I cannot refer to the CheckBox by the name provided in { Name = "chk" + varName, in the debugger a watch on "Name" returns the name of the form. I have not used this form of constructor before and am struggling to find any documentation on it. Can anybody help on this before I try to move on again please?
Is there a way to do this?
The code itself is produced by a small program where I just past in the names of variables from the main program and it produces the above, and all the vent handlers, which is an enormous time saver.
jimi - I've posted this as an answer as it's too long for a comment.
I ended up with:
Dictionary<string, Action<CheckBox>> m_Actions = new Dictionary<string, Action<CheckBox>>();
then loop through:
m_Actions.Add("chkAllowColumnReorder", (c) => containerListView1.AllowColumnReorder = c.Checked); etc.
and then:
void chkTemp_CheckedChanged(object sender, EventArgs e)
{
CheckBox chkTemp = ((CheckBox)sender);
m_Actions[chkTemp.Name](chkTemp);
}
This is completely new to me and I'm still not sure how (or why) it works but thank you very much for telling me about it - I can now paste variables in to my app's form and produce all the code to add controls to the app I need to test.
I did it because my heart sank at the thought of adding heaps of CheckBoxes to an app to test an ExtendeListView, in the end writing this to produce the code was much more interesting than the testing!

How to update value of a "usercert" property in LDAP AD

I have a requirement where I need to update the value saved in the property ("usercert") of a computer present in active directory.
// Retrieving properties value from AD
DirectoryEntry entry = new DirectoryEntry(LDAPPath, LDAPUser, DecryptPwd(LDAPPwd, LDAPKey));
DirectorySearcher searcher = new DirectorySearcher(entry);
searcher.Filter = string.Format("(&(objectCategory=computer)(Name=" + MachineName + "))");
result = searcher.FindOne();
byte[] text= (byte[])result.GetDirectoryEntry().Properties["usercert"].Value;
// Updateing new value to AD string updatedText= "New Text";
if (result.GetDirectoryEntry().Properties["usercert"] != null &&
result.GetDirectoryEntry().Properties["usercert"].Value != null)
{
byte[] updatedTextByte = Encoding.ASCII.GetBytes(updatedText);
result.GetDirectoryEntry().InvokeSet("usercert", updatedPassByte);
//(result.GetDirectoryEntry().Properties["usercert"]).Value = Encoding.ASCII.GetBytes(updatedText);
//result.GetDirectoryEntry().Properties["usercert"].Add(Encoding.ASCII.GetBytes(updatedText));
//result.GetDirectoryEntry().Properties["usercert"][0] = Encoding.ASCII.GetBytes(updatedText);
result.GetDirectoryEntry().CommitChanges();
}
I tried with all of the above commented code but nothing works for me. Can you please help me to solve this issue.
Calling GetDirectoryEntry() creates a new DirectoryEntry object each time you call it, which you can see in the source code here.
So when you do this:
result.GetDirectoryEntry().CommitChanges();
It's creating a brand new DirectoryEntry object and calling CommitChanges() on that. So nothing is changed.
You will need to call GetDirectoryEntry() only once and make changes to that object. For example:
var resultDe = result.GetDirectoryEntry();
resultDe.Properties["usercert"]).Value = whatever;
resuleDe.CommitChanges();

Why does this FilterEventHandler seem to remain in the CollectionViewSource filter even after the filter is set to null?

Summary:
I'm creating a simple application for practice, where the user can maintain and query a collection of Things. On the UI are several TextBoxes and ComboBoxes with which they can filter the collection.
The three buttons I'm concerned with are [Filter], [Random], and [All]. [Filter] applies the current filter options. [Random] applies the current filter options (if any), and then only shows one random entry from the filtered results. [All], as expected, shows the unfiltered collection.
To fully understand the background for the question, I'll provide the relevant code.
Here is where anything having to do with the CollectionViewSource (or any relevant code I'm posting) gets declared:
//Members
private ObservableCollection<Thing> _myDataCollection;
private CollectionViewSource _CVS;
private Thing _randomThing;
//Properties
public ObservableCollection<Thing> MyDataCollection
{
get { return _myDataCollection; }
set
{
if (_myDataCollection!= value)
{
_myDataCollection= value;
RaisePropertyChanged(() => MyDataCollection);
}
}
}
public CollectionViewSource CVS
{
get { return _CVS; }
set
{
if (_CVS != value)
{
_CVS = value;
RaisePropertyChanged(() => CVS);
}
}
}
public ICollectionView CVSView
{
get { return CVS.View; }
}
Here is where the CVS is initialized (in the window view-model's constructor). For now, the data collection is populated with a ton of random things (that's all that RandomizeData() does).
MyDataCollection = new ObservableCollection<Thing>();
RandomizeData();
CVS = new CollectionViewSource();
CVS.Source = MyDataCollection;
Here is the code for the [Filter] button's command:
//Clear any stale filter options and rebuild with the most current ones.
CVSView.Filter = null;
//IF THE FOLLOWING LINE IS UNCOMMENTED, THE ISSUE OCCURS.
//CVS.Filter -= new FilterEventHandler(SingleRandomFromCollectionFilter);
BuildCVSFilter();
The code for the [All] button literally just clears the filter:
CVSView.Filter = null;
The code for the [Random] button. I suspect the issue is coming from the handler added here.
//Clear any stale filter options and rebuild with the most current ones.
CVSView.Filter = null;
//IF THE FOLLOWING LINE IS UNCOMMENTED, THE ISSUE OCCURS.
//CVS.Filter -= new FilterEventHandler(SingleRandomFromCollectionFilter);
BuildCVSFilter();
//Only proceed if there are actually results in the filtered collection.
int resultsCount = CVSView.Cast<Thing>().Count();
if (resultsCount > 0)
{
//Point to a random thing in the filtered collection.
CVSView.MoveCurrentToPosition(random.Next(0, resultsCount));
_randomThing = CVSView.CurrentItem as Thing;
//Add another filter event that further constrains the collection to only contain the random thing.
CVS.Filter += new FilterEventHandler(SingleRandomFromCollectionFilter);
}
And here is the code for that BuildCVSFilter() I've been calling. I use this so that I can use multiple filters concurrently. The "FilterOption" strings are properties that are bound to the values of the UI controls.
if (!string.IsNullOrEmpty(FilterOption1))
{
CVS.Filter += new FilterEventHandler(Fitler1);
}
if (!string.IsNullOrEmpty(FilterOption2) && FilterOption2 != "ignore")
{
CVS.Filter += new FilterEventHandler(Fitler2);
}
if (!string.IsNullOrEmpty(FilterOption3))
{
CVS.Filter += new FilterEventHandler(Filter3);
}
Each filter that gets added this way only sets e.Accepted to false, if applicable, and leaves it alone if it's true.
Issue:
If I click on [Random] at all, it seems like the FilterEventHandler that gets added there does not go away. This makes it so that selecting [Filter] after [Random] won't work as expected, because it's only going to filter from the current collection of one thing. Additionally, selecting [Random] a second time seems to reuse the same random thing (instead of finding a new one). Interestingly enough, clicking [All] still works just fine. It shows everything.
When I go into those [Filter] and [Random] OnCommand methods and explicitly add a line to remove that SingleRandomFromCollectionFilter handler, everything works as expected.
Why would NameEntriesView.Filter = null; work to clear the filter on [All], but not on [Filter] or [Random]? Is there something about the CollectionViewSource and its implementation that I'm not fully understanding?

DataGridViewComboBoxCell Value Not Updating When Set Programmatically C# Winforms

I've read all the similiar posts about this darn control (DataGridViewComboBoxCell) and setting it's value programmatically but implementing all the suggestions hasn't worked. I could probably change the UI to get around this problem but I don't like to be beat!
private void PopulateAreaForRoleAssociation()
{
// If businessRoleList is null then no data has been bound to the dgv so return
if (businessRoleList == null)
return;
// Ensure businessArea repository is instantiated
if (businessAreaRepository == null)
businessAreaRepository = new BusinessAreaRespository();
// Get a reference to the combobox column of the dgv
DataGridViewComboBoxColumn comboBoxBusinessAreaColumn = (DataGridViewComboBoxColumn)dgvBusinessRole.Columns["BusinessArea"];
// Set Datasource properties to fill combobox
comboBoxBusinessAreaColumn.DisplayMember = "Name";
comboBoxBusinessAreaColumn.ValueMember = "Id";
comboBoxBusinessAreaColumn.ValueType = typeof(Guid);
// Fill combobox with businessarea objects from list out of repository
comboBoxBusinessAreaColumn.DataSource = businessAreaRepository.GetAll();
// loop through the businessRoles list which the dgv is bound to and get out each dgv row based upon the current id in the loop
businessRoleList.Cast<BusinessRole>().ToList().ForEach(delegate(BusinessRole currentRole)
{
DataGridViewRow currentRowForRole = dgvBusinessRole.Rows.Cast<DataGridViewRow>().ToList().Find(row => ((BusinessRole)row.DataBoundItem).Id == currentRole.Id);
// Get a reference to the comboBox cell in the current row
DataGridViewComboBoxCell comboBoxCell = (DataGridViewComboBoxCell)currentRowForRole.Cells[2];
// Not sure if this is necessary since these properties should be inherited from the combobox column properties
comboBoxCell.DisplayMember = "Name";
comboBoxCell.ValueMember = "Id";
comboBoxCell.ValueType = typeof(Guid);
// Get the business area for the current business role
BusinessArea currentAreaForRole = businessAreaRepository.FetchByRoleId(currentRole.Id);
// if the role has an associated area then set the value of the cell to be the appropriate item in the combobox
// and update the cell value
if (currentAreaForRole != null)
{
foreach (BusinessArea area in comboBoxCell.Items)
{
if (currentAreaForRole.Id == area.Id)
{
comboBoxCell.Value = area.Id;
dgvBusinessRole.UpdateCellValue(2, comboBoxCell.RowIndex);
}
}
}
});
}
The dgv is first bound to a binding list holding BusinessRole objects, then the combobox column is bound to a basic list of BusinessArea objects that come out of a repository class. I then loop through the bindinglist and pull out the row of the dgv that is bound to the current item in the bindinglist loop.
With that row I make a database call to see if the BusinessRole entity is associated with a BusinessArea entity. If it is then I want to select the item in the combobox column that holds the BusinessAreas.
The problem is that when the grid is loaded, all the data is there and the comboboxes are populated with a list of available areas, however any values that are set are not displayed. The code that sets the value is definately getting hit and the value I am setting definately exists in the list.
There are no data errors, nothing. It's just refusing to update the UI with the value I programmatically set.
Any help would be greatly appreciated as always.
Thanks
This code works for my first combo box I have in my row with the following code, but I try it with the next one in the row and it doesn't work. I could use the help with the rest I have 3 more to do. I do set the combo boxes on a second form from this form with the same code as is on the last line of the try block but using the cell information instead of the dataset
try
{
string strQuery = "select fundCode from vwDefaultItems where IncomeType = '" + stIncome + "'";
SqlDataAdapter daDefault = new SqlDataAdapter(strQuery, conn);
DataSet dsDefault = new DataSet();
daDefault.Fill(dsDefault);
strDefFund = dsDefault.Tables[0].Rows[0].ItemArray[0].ToString();
dgvCheckEntry.Rows[curRow].Cells[7].Value = dsDefault.Tables[0].Rows[0].ItemArray[0].ToString();
}
catch (Exception eq)
{
}

object not set to instance of an object!! ComboBox SelectedIndex SelectedItem

I am developing a program which gets all Clearcase regions (basically strings) & adds them to Combo box. I compare an existing clearcase region string in newly added items in combo box & if it is found then I want to select it, but because nothing is selected for the first time, selectedItem is null & selectedIndex = -1.
when I assign 0 to selectedIndex, error comes --> object not set to instance of an object!! same problem when you assign something to selectedItem; gives an error.
whats wrong with my code?
private void PopulateClearCaseRegionComboBox ( )
{
clearCaseRegionComboBox.Items.Clear();
foreach ( Match token in RegularExpression.Match( "\\w+", clearTool.CmdExec( "lsregion" ) ) )
{
clearCaseRegionComboBox.Items.Add(token.Value.Trim());
if (clearCaseRegion.ToUpperInvariant() == token.Value.Trim().ToUpperInvariant())
{
clearCaseRegionComboBox.SelectedIndex = clearCaseRegionComboBox.Items.IndexOf(token.Value.Trim());
}
}
clearCaseRegionComboBox.Sorted = true;
}
A notification: the SelectedIndexChanged event also occurs when you set SelectedIndex or SelectedItem. So if you have something there, check it out also. :) I've passed several hours on it, because you don't see it while debugging.
Are you sure the following line returns a valid index?
clearCaseRegionComboBox.Items.IndexOf(token.Value.Trim());
The Add method returns the index of the newly added item. You can use that value inside your if statement.
private void PopulateClearCaseRegionComboBox ( )
{
clearCaseRegionComboBox.Items.Clear();
foreach ( Match token in RegularExpression.Match( "\\w+", clearTool.CmdExec( "lsregion" ) ) )
{
int index = clearCaseRegionComboBox.Items.Add(token.Value.Trim());
if (clearCaseRegion.ToUpperInvariant() == token.Value.Trim().ToUpperInvariant())
{
clearCaseRegionComboBox.SelectedIndex = index;
}
}
clearCaseRegionComboBox.Sorted = true;
}
Perhaps you can reveal more of your code in context? I say this because it would seem impossible to get this error at this point in your representative code. You've already used the object to add an item 3 lines up.
Are you sinked to any events on the combo box that would assign the clearCaseRegionComboBox variable to null?

Resources