0

In my program I have a TreeViewItem with it's Header set to a numerical integer value. In order to convert the Header to a straight int value I pass to a function called getNumber.

My getNumber function:

This function comes from this previously asked question.

//Gets the number contained in a Node's header
public static int getNumber(string parentNodeHeader)
{
    int curNumber = 0;
    Int32.TryParse(parentNodeHeader, out curNumber);
    return curNumber;
}

I pass to this function the same way in a few different areas in my program, but in one of them the string doesn't pass correctly. In the debugger it (parentNodeHeader) displays "System.Windows.Controls.StackPanel" as it's value instead of a number. I have no idea why this is happening.

For the working calls to the function, as well as the not working call I use the same code.

int curNumber = getNumber(SelectedItem.Header.ToString());

Why would this be happening and how can I fix it?

UPDATE:

I've changed my call to the getNumber function by adding this...

var selectedHeader = (TextBlock)SelectedItem.Header; //The header is now a TextBlock
int curNumber = getNumber(selectedHeader.Text);

Theoretically this should work, but I am getting an InvalidCastException that says it could not cast StackPanel to TextBlock. Where is StackPanel coming from...?

Thanks for your help.

Community
  • 1
  • 1
Eric after dark
  • 1,768
  • 4
  • 31
  • 79
  • 2
    Do you remember when I told you that [UI is not Data](http://stackoverflow.com/a/14382137/643085) and that you shouldn't be reading the UI Elements' properties? You'd already finished your application (twice) by now if you had followed my advice instead of all these horrible winforms-like hacks. – Federico Berasategui Aug 23 '13 at 19:16
  • I believe you just got scolded – Jonesopolis Aug 23 '13 at 19:17
  • 2
    @HighCore I think you're a guy who says what's on his mind, and I appreciate that. However, To me it doesn't really matter what you call my code. I understand what you are saying, but I've made more progress like this than I would ever have trying to learn MVVM from the very bottom. I know my program now, and I know how to reference the elements inside of it, so that's what I care about. – Eric after dark Aug 23 '13 at 19:22
  • @EricAfterdark still you're posting a question every 5 minutes because all your ToString() stuff blows with an exception. – Federico Berasategui Aug 23 '13 at 19:25
  • 1
    @Ericafterdark plus, blindlessly writing more and more code, instead of applying the appropiate patterns results in a crappy design, fully bloated where probably 90% of the code can be replaced by simple Bindings. – Federico Berasategui Aug 23 '13 at 19:27
  • @HighCore Probably, but I don't have time to learn something like that from scratch, I'm not at school here. Regardless of my structure, when I bring a question here it's narrowed down and specific. – Eric after dark Aug 23 '13 at 19:30
  • 1
    You're passing in a `StackPanel` object and calling `ToString()` on it. `StackPanel` doesn't have a meaningful concept of "text" or "string", so uses the default behaviour that reports the name of its type. You need to instead access and pass some kind of `TextBox` control (or whatever the UI control is contained within that `StackPanel` which has the text you want to parse). Also, you should _not_ be assigning `0` as a default value to `curNumber`; it's thrown away by the `Int32.TryParse` method. – Chris Sinclair Aug 23 '13 at 19:33
  • _Also, you should not be assigning 0 as a default value to curNumber; it's thrown away by the Int32.TryParse_ @Chris sort of...if it fails 0 is returned, and ints are 0 by default, so there really is nothing bad about it. – jamesSampica Aug 23 '13 at 19:36
  • @Chris Sinclair So by default the `Header` value of a node is a `StackPanel`? Why would it work in one place, but not in another? That's inconsistent. Are you saying that I need to make the header to this node a `TextBox` or that I can derive the text out of it differently? – Eric after dark Aug 23 '13 at 19:39
  • @Jim: It's a bad habit mostly for avoiding non-initialized usage of the variable. If you change your logic later (say `if (someCondition) { curNumber = Int32.TryParse... }`) you may never realize you have a code flow/path in which you never assign a value to `curNumber` but you _should_ have. (this is a pretty trivial case in _this_ code example, but to me this is a good habit to adopt wherever you _intend_ to write to a variable using an `out` method. If you don't do it everywhere, you're bound to forget eventually. _Plus_ it propagates the misconception that you can assign a default value.) – Chris Sinclair Aug 23 '13 at 19:39
  • @Chris Sinclair In addition, I've looked through my code, and I didn't make the node `header` I'm having trouble with into a `StackPanel`, which is what I originally thought. – Eric after dark Aug 23 '13 at 19:42
  • @Ericafterdark: IIRC, `Header` objects in tree views can be a lot of things. They can be simple `String` text, or UI elements that implement a `ToString()` method logically (perhaps `TextBox.ToString()` returns its `.Text` property), or it can contain more complex UI elements (like a `StackPanel` which contains _several_ GUI components, like an image + text + expansion icon) – Chris Sinclair Aug 23 '13 at 19:43
  • @ChrisSinclair All I'm saying is that I didn't change the `header`'s UI element. I can if I need to though. – Eric after dark Aug 23 '13 at 19:44
  • @Chris `curNumber = Int32.TryParse... ` Wouldn't even compile, I don't see your point... – jamesSampica Aug 23 '13 at 19:44
  • @Jim: Sorry, that was a mistake in my example. Correction: `if (someCondition) { Int32.TryParse(parseNodeHeader, out curNumber); }`. Point is, assigning an initial value a) _looks_ like you're specifying a default value when you're not, and b) throws out any static analysis of definite assignment before use. The above case here might be trivial and not really an issue for these two points, but it's a bad habit that shouldn't be encouraged. – Chris Sinclair Aug 23 '13 at 19:50
  • I've updated my question based off of @Chris' comment. My nodes' `header` is now in a `TextBlock`. – Eric after dark Aug 23 '13 at 19:52
  • @Ericafterdark: Regarding your question edit: "should work" it definitely _won't_. It's _not_ a `TextBlock`, it's a `StackPanel`. You can't just cast between two non-convertable types. Obviously _somewhere_ `StackPanel` objects are being used in your header, either explicitly in your code somewhere, or as part of a XAML styling. Perhaps instead you can cast to `StackPanel`, and iterate its `Children` collection to find the `TextBlock` containing your header information. (Better yet, _fix_ your design as HighCore suggests) – Chris Sinclair Aug 23 '13 at 19:53
  • @Chris I agree to disagree, I don't want to detract any further from the question. – jamesSampica Aug 23 '13 at 19:59
  • @Chris Are `StackPanels` inherited in `TreeViews`? The parent of the selected node has it's header set to a `StackPanel`. – Eric after dark Aug 23 '13 at 20:02
  • @Ericafterdark: I wouldn't say "inherited". But IIRC, they _can_ be _any_ GUI element. So... yes? Why not be a `StackPanel`? – Chris Sinclair Aug 23 '13 at 20:04
  • @Chris I was just wondering because it's not set as one, but it's parent is, so it must be inheriting in some way. The call to the function that worked has a parent whos `header` is not set to a `StackPanel`. – Eric after dark Aug 23 '13 at 20:07
  • Sorry, Eric, I don't know past this. I _think_ the content of the headers are _not_ inherited from their parent nodes. Maybe check your XAML styling and maybe post the code where you're assigning the `Header` content. – Chris Sinclair Aug 23 '13 at 20:09

1 Answers1

1

Instead of using the getNumber() function I used Regex to extract the integer from the string.

In order to use Regex you need to include System.Text.RegularExpressions;

Then you implement it like so: var data = Regex.Match(stringValue, @"\d+").Value;

Eric after dark
  • 1,768
  • 4
  • 31
  • 79