0

I am using LINQ to create tables in a WPF application, but when I try to access one of those tables using an event method, my compiler tells me "The name 'parts' does not exist in the current context". Is there something I should do to adjust the scope so that I can access a var from a separate method?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 FinalExam_SupplierPartsWPF
{

public partial class MainWindow : Window
{

    public MainWindow()
    {
        InitializeComponent();

        var suppliers = new[] {
            new{SN = 1, SName = "Smith", Status = 20, City="London"},
            new{SN = 2, SName = "Jones", Status = 10, City="Paris"},
            new{SN = 3, SName = "Blake", Status = 30, City="Paris"},
            new{SN = 4, SName = "Clark", Status = 20, City="London"},
            new{SN = 5, SName = "Adams", Status = 30, City="Athens"}
        };

        var parts = new[] {
            new{PN = 1, PName="Nut", Color = "Red", Weight = 12, City="London"},
            new{PN = 2, PName="Bolt", Color = "Green", Weight = 17, City="Paris"},
            new{PN = 3, PName="Screw", Color = "Blue", Weight = 17, City="Rome"},
            new{PN = 4, PName="Screw", Color = "Red", Weight = 14, City="London"},
            new{PN = 5, PName="Cam", Color = "Blue", Weight = 12, City="Paris"},
            new{PN = 6, PName="Cog", Color = "Red", Weight = 19, City="London"}
        };

        var shipment = new[] {
            new{SN = 1, PN = 1, Qty=300},
            new{SN = 1, PN = 2, Qty=200},
            new{SN = 1, PN = 3, Qty=400},
            new{SN = 1, PN = 4, Qty=200},
            new{SN = 1, PN = 5, Qty=100},
            new{SN = 1, PN = 6, Qty=100},
            new{SN = 2, PN = 1, Qty=300},
            new{SN = 2, PN = 2, Qty=400},
            new{SN = 3, PN = 2, Qty=200},
            new{SN = 4, PN = 2, Qty=200},
            new{SN = 4, PN = 4, Qty=300},
            new{SN = 4, PN = 5, Qty=400}
        };

        IEnumerable<string> colorList = parts
            .OrderBy(part => part.Color)
            .Select(part => part.Color)
            .Distinct();

        foreach (string x in colorList)
            cbxColorSelect.Items.Add(x);

    }

    private void ColorSelectedEvent(object sender, SelectionChangedEventArgs e)
    {
        lbxPartDisplay.Items.Add("test");
        string colorChoice = cbxColorSelect.Text;

        IEnumerable<string> partResults = parts
            .Where(clr => String.Equals(clr.Color, colorChoice))
            .Select(part => String.Format("{0}", part.PName));

        foreach (string y in partResults)
            lbxPartDisplay.Items.Add(y);
    }
}

}

1
  • 6
    This has nothing to do with LINQ - it's basic C#. You can't access the local variables of one method from another. The MainWindow constructor has completed by the time ColorSelectedEvent runs... the variable is long gone. If you need to keep it, you'll need it to be a field rather than a local variable. I would strongly recommend that you learn the basics of C# with console apps before moving onto GUIs - there are a lot fewer moving parts to worrying about that way. Commented Jul 25, 2015 at 20:25

1 Answer 1

1

The parts, suppliers and shipments variables are declared in the scope of the MainWindow() method; they will not be accessible anywhere outside of this method. If you want to access these variables in another method within the same class, you should declare them as private to the class.

When a variable is declared, you typically specify an access modifier. In your example, you are creating the variables implicitly using the var keyword. Variables created in such a manner have a default access modifier of private. This means that they are scoped to they containing block in which they are created, which in your case is the MainWindow() method. As others have suggested, I would recommend a review of variable scope and access modifiers. You will need to have a solid grasp of these basics to be productive.

Check out this channel 9 video series on some C# fundamentals for beginners; specifically, episode 5 focuses on variables. This blog post also goes over some basics on variable scope.

The var keyword used for variable declaration means that the variable is implicitly defined based on the assignment. What this means is that the compiler will look at what you are assigning to the variable (ie: what is on the right side of the equals sign) and figure out the type. For technical reasons, you cannot use the var declaration operator for variables defined at the class level (also often referred to as 'fields' of a class if they are private to the class).

Since you cannot use the var keyword to define your class level variables, you must explicitly specify a type. In the example below, I have created a class which represents the original parts anonymous type you were working with in your example.

I also concur with the advice of other on starting out learning C# using a console application. GUI applications bring a lot of other nuances to the table which can only serve to confuse you and cause general frustration when you are learning a language. For example: simple things such as updating a textbox from the non GUI thread with a new value can bomb your program and leave you wondering why it doesn't work.

You can choose to continue to work with an array of anonymous types, however you would need to declare it as dynamic or object. Working with an array of anonymous objects can be a little more challenging. I would recommend that you use a defined type (such as the one part class have illustrated below) for your class fields.

for example:

public class Part
{
    public int PN { get; set; }
    public String PName { get; set; }
    public String Color { get; set; }
    public int Weight { get; set; }
    public String City { get; set; }
}

public partial class MainWindow : Window
{

    private List<Part> _parts;
    public MainWindow()
    {
        InitializeComponent();

        _parts.Add(new Part() { PN = 1, PName = "Nut", Color = "Red", Weight = 12, City = "London" });
        _parts.Add(new Part() { PN = 2, PName = "Bolt", Color = "Green", Weight = 17, City = "Paris" });
        _parts.Add(new Part() { PN = 3, PName = "Screw", Color = "Blue", Weight = 17, City = "Rome" });
        _parts.Add(new Part() { PN = 4, PName = "Screw", Color = "Red", Weight = 14, City = "London" });
        _parts.Add(new Part() { PN = 5, PName = "Cam", Color = "Blue", Weight = 12, City = "Paris" });
        _parts.Add(new Part() { PN = 6, PName = "Cog", Color = "Red", Weight = 19, City = "London" });

    }

    private void SomeMethod()
    {
        string colorChoice = "Blue";

        IEnumerable<string> partResults = _parts
            .Where(clr => String.Equals(clr.Color, colorChoice))
            .Select(part => String.Format("{0}", part.PName));
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

When I try to add it outside of MainWindow() as you did I get the compiler error "The type or namespace 'var' could not be found"
@shampouya: please read some basic documentation. You can't use var for class member definitions.
@shampouya: I have updated my answer to hopefully provide you some additional details on the usage of var, variable declarations and scope. I wish you well learning they C# language.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.