tags:

views:

104

answers:

1

In code behind file of the main window of WPF application I have a method quering a database with LINQ to SQL and writing results to an ObservableCollection:

    public void GetStateByDate(string shcode)
    {
        MydbDataContext contextSts = new MydbDataContext();
        _ShAvaQuCollection.Clear();

        var sts = from p in contextSts.SAties where p.ShID == shcode select p;

        foreach (var p in sts)
            _ShAvaQuCollection.Add(new ShAvaQu
            {
                ShCode = p.ShID,
                SiID = p.SiID,
                PrCat = p.PrCat
            });
    }

When I call this method from the same code behind file (the same window), everything is OK.

If I call this method from another window, using an instanse of the main window, ObservableCollection remains empty.:

SWindow sw = new SWindow();
sw.GetStateByDate(stringpar);

What is the reason for this? Does in this case method create yet another instance of ObservableCollection?

(I can see in debugger that sw._ShAvaQuCollection contains values. Is sw._ShAvaQuCollection not the same instanse of collection as _ShAvaQuCollection? If yes, how it can be resolved?)

Edited (added)

The ObservableCollection declared this way:

    ObservableCollection<ShAvaQu> _ShAvaQuCollection =
            new ObservableCollection<ShAvaQu>();

    public ObservableCollection<ShAvaQu> ShAvaQuCollection
    { get { return _ShAvaQuCollection; } }

    public class ShAvaQu
    {
        public string ShCode { get; set; }
        public string SiID { get; set; }
        public int PrCat { get; set; }
    }

I call the method from a window, where another collection ShQuCollection displayed through ListView. In SelectionChanged event handler I take an argument for this database quering:

private void ShSelList_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {           
        SWindow sw = new SWindow();         
        string str = sw.ShQuCollection[ShSelList.SelectedIndex].ShCode;
        sw.GetStateByDate(str);
        Close();
    }
}
+2  A: 

1) Most importantly you shouldn't be calling db logic from you windows / forms. You should abstract it out into another class. Then you could have your method return a observable collection.

However in your case I am assuming that you are trying to use the secondary form to reload / load the collection and you want it used on your primary form. The problem with this is you are creating a new instance of the form so your collection is being populated but not on your main form but a copy.

There are a couple ways you can try to get around that.

1) Make the method static and your observable collection static so that it updates a single instance.

2) Pass an instance handle of your primary form into your secondary form so that you re-use the instance you already have. This would be preferable so that you are not creating new instances all over the place.

In the constructor of the second form you could pass in the instance of your primary window so then you can use it directly. This should solve your problem.

UPDATE: Here is some code samples. Basically there are many ways to pass a reference.

You could do it like this with a constructor:

// This is the constructor for your second window
private Window _parentHandle;

public SecondWindow(Window obj)
{
    this._parentHandle = obj;
}

Then from your primary form that has the method you would open that window like this.

SecondWindow w = new SecondWindow(this);
w.Show();

Now your second window has a direct handle to your first window so you can call your method on that variable and it will update.

Another way is to have a public Setter method on your second window as well.

public Window ParentContext
{
   get { return this._parentHandle; }
   set { this._parentHandle = value; }
}

Then you could create your form instance like this:

SecondWindow w = new SecondWindow();  // so just like normal
w.ParentContext = this; // set the instance to the calling form
w.Show();

That is the basics. This type of scenario works in just about any scenario where you need to pass a reference.

Hope that helps.

Joshua Cauble
Thanks, Joshua! Please, could you show in code example the correct way of passing an instance handle of the primary form into the secondary form?
rem
And yet another point to note regarding my case: it is WPF app. Will it be posiible to pass an instance handle in this case?
rem
Joshua, thank you for your help!
rem