C
C#2y ago
doolhofx

❔ Need help with Event Handlers to update a field.

I am making a unit conversion program in C# wpf as my first C# application. I have created a method that calculates the conversion from for example mm to m. It has 3 inputs, Input Unit - Output Unit - Input Value. Calculates the Output Value. I want to update the Output Value on 3 different events, InputWaarde_TextChanged or InputEenheid_SelectionChanged or OutputEenheid_SelectionChanged. But when I have the method in those event handlers I get the following error when I start the program and select a unit, both input or output or when I fill in a value.
System.NullReferenceException
System.Windows.Controls.Primitives.Selector.SelectedItem.get returned null.
System.NullReferenceException
System.Windows.Controls.Primitives.Selector.SelectedItem.get returned null.
Anyone has an idea on how to solve it? And is anyone willing to look at the rest of the code to give feedback? I think I can use some haha!
private void InputWaarde_TextChanged(object sender, TextChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);

}

private void InputEenheid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);

}

private void OutputEenheid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);

}
private void InputWaarde_TextChanged(object sender, TextChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);

}

private void InputEenheid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);

}

private void OutputEenheid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);

}
110 Replies
JakenVeina
JakenVeina2y ago
the error is pretty self-explanatory SelectedItem.get returned null I.E. there is no selected item what do you expect your program to do when there is no selected item in those selectors? decide that, then write the code to do it
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
doolhofx
doolhofxOP2y ago
Thanks for your response! Sorry for my late answer I got a kindof hectic week. By default nothing is selected, that is true now I understand that now. But how can I set a default value in a combobox? I am searching on google, but I tried a few ways that did not work. Then It should be solved, right? If I make that it can never return null anymore
JakenVeina
JakenVeina2y ago
if you want a "default" value selected, then set one you're the one in charge of creating the combobox, you have full control over its state upon creation all of that is really irrelevant to the error what do you expect your app to do when nothing is selected?
doolhofx
doolhofxOP2y ago
Just nothing, because it doesn't know what to do But it's ok if there is always a default state selected.
JakenVeina
JakenVeina2y ago
then that's what you need to code for that's not what "default state" means setting a default selection of not nothing doesn't stop the user from selecting nothing
doolhofx
doolhofxOP2y ago
It is, because there is no reason and possablity to select nothing
doolhofx
doolhofxOP2y ago
It only starts as "null" untill you choose an option and then you can never get a "null" again
JakenVeina
JakenVeina2y ago
I would say this isn't a combobox, then this is the WPF ComboBox class?
doolhofx
doolhofxOP2y ago
Yes
JakenVeina
JakenVeina2y ago
I guess I'm not familiar enough with it if it's legitimately impossible for the user to select nothing within the control, then yeah, setting a default value should work
doolhofx
doolhofxOP2y ago
Indeed, but I am now watching the next youtube video maybe I get it working now. I hope I have the default selected index now! But now I get the same error that SelectedItem.get returned null. So I set it in a try catch and with an if( .... != null) then ..........
JakenVeina
JakenVeina2y ago
it's either being called before you set the index, or it doesn't work that way, and you should set the item directly
doolhofx
doolhofxOP2y ago
But still error, and when I press F5 again, I get my UI screen and it works fine
JakenVeina
JakenVeina2y ago
absolutely not
doolhofx
doolhofxOP2y ago
?
JakenVeina
JakenVeina2y ago
do not try/catch the exception fix the problem so that the exception never occurs
doolhofx
doolhofxOP2y ago
I set the index directly to index [0] at the ComboBox properties That is indeed a good idea haha
JakenVeina
JakenVeina2y ago
huh?
doolhofx
doolhofxOP2y ago
If you place a combobox you get it's properties on the right side, there I set the default index to 0 instead of -1
JakenVeina
JakenVeina2y ago
stop using the visual designer immediately and I'm going to guess what's happening is that setting accomplishes nothing because it happens on construction when that property is set, there IS no item at index 0. The items get added later on, when your business logic populates them, at which point the index setting of 0 either has already been wiped out, because it was invalid to begin with, or it just doesn't trigger a re-calculation of the SelectedItem property
doolhofx
doolhofxOP2y ago
It does actually select a default value now But I understand what you mean. Uuh oke but how would you take on this problem then? I really have no idea what I can try anymore Or what I need to change
JakenVeina
JakenVeina2y ago
stop beating around the bush if you want SelectedItem to not be null, then SET IT.
doolhofx
doolhofxOP2y ago
I know that I need to set it, but where or how I found a way of setting it by changing the selectedIndex to 0
JakenVeina
JakenVeina2y ago
did you not say specifically that that does NOT set SelectedItem? how about the same place and way that you're setting Items?
doolhofx
doolhofxOP2y ago
It does set it
JakenVeina
JakenVeina2y ago
disagree
doolhofx
doolhofxOP2y ago
In the MainWindow
public partial class MainWindow : Window
{
public string[] eenheden { get; set; }

public MainWindow()
{
InitializeComponent();

eenheden = new string[] { "mm", "cm", "dm", "m" };

DataContext = this;
}
public partial class MainWindow : Window
{
public string[] eenheden { get; set; }

public MainWindow()
{
InitializeComponent();

eenheden = new string[] { "mm", "cm", "dm", "m" };

DataContext = this;
}
Eenheden is the array of values
JakenVeina
JakenVeina2y ago
sweet so, if DataContext is the method by which you're passing data down to child controls
doolhofx
doolhofxOP2y ago
ItemsSource="{Binding eenheden}" SelectionChanged="InputEenheid_SelectionChanged" SelectedIndex="0"
ItemsSource="{Binding eenheden}" SelectionChanged="InputEenheid_SelectionChanged" SelectedIndex="0"
` This is part of the XAML code for the combobox
JakenVeina
JakenVeina2y ago
the data that you need to pass down now consists of both an array of values and an initial selection
doolhofx
doolhofxOP2y ago
Yea indeed, so the array of values is done. But now the initial selection
JakenVeina
JakenVeina2y ago
indeed
doolhofx
doolhofxOP2y ago
InputEenheid.SelectedIndex = 0;
OutputEenheid.SelectedIndex = 0;
InputEenheid.SelectedIndex = 0;
OutputEenheid.SelectedIndex = 0;
This? This works^, but now in the InputEenheid_SelectionChanged it get's stuck Found the problem! I have a method that requires 3 inputs as string. The InputUnit, the OutputUnit and the Value. Now I placed:
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), "m", "15");
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), "m", "15");
and it works. But when I change that "m" to OutputEenheid.SelectedItem.ToString() and keep the rest the same it breaks. So it only get's stuck on this:
OutputEenheid.SelecteItem.ToString()
OutputEenheid.SelecteItem.ToString()
But it is exactly the same as InputEenheid.SelectedItem.ToString() so idk why it doesn't understand it And that same method is also called in another section in InputWaarde_TextChanged and there it works fine Wait, can a method be called 2 times in different moments with the same parameters?
JakenVeina
JakenVeina2y ago
uhmmm..... yes?
doolhofx
doolhofxOP2y ago
Can't I "run" the method:
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);
in an if statement, placed in the MainWindow that is only run if InputWaarde_TextChanged or InputEenheid_SelectionChanged or OutputEenheid_SelectionChanged is true?
JakenVeina
JakenVeina2y ago
I really haven't the slightest clue where we've gone here what does any of this have to do with setting SelectedItem?
doolhofx
doolhofxOP2y ago
That block of code above is the only thing I want to execute on the change of one of 3 events. Events are: private void InputWaarde_TextChanged(object sender, TextChangedEventArgs e) private void InputEenheid_SelectionChanged(object sender, SelectionChangedEventArgs e) private void OutputEenheid_SelectionChanged(object sender, SelectionChangedEventArgs e)
JakenVeina
JakenVeina2y ago
okay I.E. you have logic you want to run any time any of the 3 inputs changes regardless of which one changed
doolhofx
doolhofxOP2y ago
Exactly Or the Input Unit changed, or the Output unit changed, or the value changed then update Output value And those changed events are the ones I sent above
JakenVeina
JakenVeina2y ago
okay and what's the problem with that?
doolhofx
doolhofxOP2y ago
I can't get it to work
JakenVeina
JakenVeina2y ago
why?
doolhofx
doolhofxOP2y ago
I know how I want it to work, but it doesn't
JakenVeina
JakenVeina2y ago
what's not working about it?
doolhofx
doolhofxOP2y ago
I can't place InputWaarde_TextChanged into an if statement, because it isn't a bool it's an, correct me if I am wrong, object? I think
JakenVeina
JakenVeina2y ago
it is a method
doolhofx
doolhofxOP2y ago
method, indeed
JakenVeina
JakenVeina2y ago
which is, in fact, not a bool why do you think you want to put that into an if statement?
doolhofx
doolhofxOP2y ago
if( x or y or z) then execute the method
JakenVeina
JakenVeina2y ago
what are the conditions a, b, and c?
doolhofx
doolhofxOP2y ago
the events
JakenVeina
JakenVeina2y ago
exactly so, not conditions an event is something that OCCURS not something you can CHECK
doolhofx
doolhofxOP2y ago
Ooh, so an event is not like a bool that is true or false?
JakenVeina
JakenVeina2y ago
put differently... the CHECK for whether an event is occurring or not has already occurred that decision has already been made
doolhofx
doolhofxOP2y ago
Ooh like this
JakenVeina
JakenVeina2y ago
the TextBox has already determined that the text within itself has in fact changed, and thus it's raising the event it's not on you to make a decision about whether the event is occurring, you know it's occurring, it's up to you ti write code to DO something in response that's what your methods are, they're event handlers
doolhofx
doolhofxOP2y ago
If you say it, it's actually prety logical
JakenVeina
JakenVeina2y ago
that get attached to the events on the silource component
doolhofx
doolhofxOP2y ago
So do I need to place my method:
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);
Inside those 3 event handlers?
JakenVeina
JakenVeina2y ago
correct
doolhofx
doolhofxOP2y ago
But that did not work, then I got the errors. That was what I first got Let me try again
JakenVeina
JakenVeina2y ago
what errors?
doolhofx
doolhofxOP2y ago
JakenVeina
JakenVeina2y ago
what's null?
doolhofx
doolhofxOP2y ago
JakenVeina
JakenVeina2y ago
so, we're back to you needing to set SelectedItem
doolhofx
doolhofxOP2y ago
I found that if I remove
OutputEenheid.SelectedItem.ToString()
OutputEenheid.SelectedItem.ToString()
From event handler InputEenheid_SelectionChanged it works
JakenVeina
JakenVeina2y ago
correct, then you are no longer attempting to call .ToString() upon a value that may be null
doolhofx
doolhofxOP2y ago
But I do the same thing in the 2 other events
JakenVeina
JakenVeina2y ago
okay if SelectedItem can be null, then they are subject to the same issue
doolhofx
doolhofxOP2y ago
Hmm Uuh, so it thinks it can be null or is it null in that event case? I got it now! I thinK!
JakenVeina
JakenVeina2y ago
the value of SelectedItem can be null as evidenced by the fact that it is when the error occurs what "it" are you asking about whether it "thinks" the value can be null?
doolhofx
doolhofxOP2y ago
So it first updates the default value of InputEenheid, then it calls the event InputEenheid_Selection changed. That calls my method that finds out that OutputEenheid.SelectenItem = null!
JakenVeina
JakenVeina2y ago
that sounds reasonable
doolhofx
doolhofxOP2y ago
How can we solve this? Wow this is something I didn't think of earlier
JakenVeina
JakenVeina2y ago
particularly if all of that is happening BEFORE you've set items into the control SelectedItem is (perhaps) null because you've told it to select index 0, but there IS no item at index 0, because Items is empty, because the logic that adds items has yet to run you have 2 possible solutions
doolhofx
doolhofxOP2y ago
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace OmrekenApp_V1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public string[] eenheden { get; set; }
public bool kanweg1;

public MainWindow()
{
InitializeComponent();

eenheden = new string[] { "mm", "cm", "dm", "m" };
InputEenheid.SelectedIndex = 0;
OutputEenheid.SelectedIndex = 0;

DataContext = this;

}

private void InputWaarde_TextChanged(object sender, TextChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);

}

private void InputEenheid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), "m", InputWaarde.Text);

}

private void OutputEenheid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);

}

}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace OmrekenApp_V1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public string[] eenheden { get; set; }
public bool kanweg1;

public MainWindow()
{
InitializeComponent();

eenheden = new string[] { "mm", "cm", "dm", "m" };
InputEenheid.SelectedIndex = 0;
OutputEenheid.SelectedIndex = 0;

DataContext = this;

}

private void InputWaarde_TextChanged(object sender, TextChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);

}

private void InputEenheid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), "m", InputWaarde.Text);

}

private void OutputEenheid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);

}

}
}
JakenVeina
JakenVeina2y ago
A) account for the possibility that SelectedItem can be null, and decide what you want to do in that scenario, then code for that B) prevent SelectedItem from being null
doolhofx
doolhofxOP2y ago
This is my code if that helps
JakenVeina
JakenVeina2y ago
not really
doolhofx
doolhofxOP2y ago
How can I do B, prevent SelectedItem from being null?
JakenVeina
JakenVeina2y ago
depends you can set it or you can try and understand why it's null now and code around whatever scenario is causing that
doolhofx
doolhofxOP2y ago
I do understand why it's null now. But I can't get around that. Because for me it's selecting the index of both input and output at the same time. But the code first does
InputEenheid.SelectedIndex = 0;
InputEenheid.SelectedIndex = 0;
Now triggers the event handler which sees that OutputEenheid is still null because index is at -1. Gives an error for that And then
OutputEenheid.SelectedIndex = 0;
OutputEenheid.SelectedIndex = 0;
JakenVeina
JakenVeina2y ago
what is your understanding of why it's null? are you referring to my explanation a little bit ago? I only proposed that as a possibility
doolhofx
doolhofxOP2y ago
No
JakenVeina
JakenVeina2y ago
I don't know if that's accurate, but it does make sense for clarity then, what is your understanding? oh, nevermind, I see
doolhofx
doolhofxOP2y ago
It makes sense, because when I remove the OutputEenheid.SelectedItem.ToString() from the first event handler for InputEenheid_SelectionChanged then I don't have any errors because it is able to set both InputEenheid and OutputEenheid to != null
JakenVeina
JakenVeina2y ago
so, yeah, because of the interdependencies between these inputs, and the nature of how ComboBox works, I would say option B) is impossible
doolhofx
doolhofxOP2y ago
So for option A then, act on the possibility that it can happen. Uuuh how Place an if in my method that only executes code if (OutputEenheid.SelectenItem != null) ?
JakenVeina
JakenVeina2y ago
that would do it if we assume that the nulls can only occur during construction, and never because the user selected it, then "do nothing" is an acceptable answer for "what do I want the app to do when nothing is selected"
doolhofx
doolhofxOP2y ago
Uh nope, because my method expects a string and I can't convert null to string and then check if != null
JakenVeina
JakenVeina2y ago
uhm no just no you do not "convert" null to string
doolhofx
doolhofxOP2y ago
I do, look:
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);
JakenVeina
JakenVeina2y ago
yes
doolhofx
doolhofxOP2y ago
And OutputEenheid.SelectedItem returns null
JakenVeina
JakenVeina2y ago
you are invoking .ToString() on SelectedItem when it can be null don't do that you just said you want to check for null do that
doolhofx
doolhofxOP2y ago
So place the .ToString inside the Method?
JakenVeina
JakenVeina2y ago
place it wherever you like just do a null check first
doolhofx
doolhofxOP2y ago
But
private void InputWaarde_TextChanged(object sender, TextChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);

}
private void InputWaarde_TextChanged(object sender, TextChangedEventArgs e)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);

}
It can't be here, right?
JakenVeina
JakenVeina2y ago
what can't? the null check?
doolhofx
doolhofxOP2y ago
yes
JakenVeina
JakenVeina2y ago
why not?
doolhofx
doolhofxOP2y ago
Because the .ToString is connected to a parameter inthe method
JakenVeina
JakenVeina2y ago
no, ToString() is a method upon all objects which is why you're using it to convert your SelectedItem values back to string which is one of many ways you could be doing that that's mostly unrelated to the fact that the business method you want to call requires 3 string parameters which, at the moment, should not be null
doolhofx
doolhofxOP2y ago
Got it
private void InputWaarde_TextChanged(object sender, TextChangedEventArgs e)
{
if (InputEenheid.SelectedItem != null && OutputEenheid.SelectedItem != null && InputWaarde.Text != null)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);
}
}
private void InputWaarde_TextChanged(object sender, TextChangedEventArgs e)
{
if (InputEenheid.SelectedItem != null && OutputEenheid.SelectedItem != null && InputWaarde.Text != null)
{
OutputWaarde.Text = Formules.Lengte(InputEenheid.SelectedItem.ToString(), OutputEenheid.SelectedItem.ToString(), InputWaarde.Text);
}
}
No error's anymore, Thanks man!
JakenVeina
JakenVeina2y ago
😉
doolhofx
doolhofxOP2y ago
Short awnser, I start to like C# a bit more again haha
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server