I am working on a WPF app using the MVVM patterm, which I am learning. It uses EF4. I am trying to use a similar tabbed document interface style; several combo boxes on these tabs have the same items sources (from a sql db). Since this data almost never changes, it seemed like a good idea to make a repository object to get them when the app starts, and just reuse them for each viewmodel. For whatever reason though, even though I use new in the constructors, the lists are connected.
If I set a bound combo box on one tab, it gets set on another (or set when a new tab is created). I don't want this to happen, but I don't know why does.
The repository object is initialized before anything else, and just holds public lists. The views simply use items source binding onto the ObservableCollection. I am using the ViewModelBase class from the article. Here is the Viewmodel and model code.
ViewModel
TicketModel _ticket;
public TicketViewModel(TableRepository repository)
{
_ticket = new TicketModel(repository);
}
public ObservableCollection<Customer> CustomerList
{
get { return _ticket.CustomerList; }
set
{
if (value == _ticket.CustomerList)
return;
_ticket.CustomerList = value;
//base.OnPropertyChanged("CustomerList");
}
}
Model
public ObservableCollection<Customer> CustomerList { get; set; }
public TicketModel(TableRepository repository)
{
CustomerList = new ObservableCollection<Customer>(repository.Customers);
}
EDIT: I am sure this is the wrong way to do this, I am still working on it. Here is the new model code:
public TicketModel(TableRepository repository)
{
CustomerList = new ObservableCollection<Customer>((from x in repository.Customers
select
new Customer
{
CM_CUSTOMER_ID = x.CM_CUSTOMER_ID,
CM_FULL_NAME = x.CM_FULL_NAME,
CM_COMPANY_ID = x.CM_COMPANY_ID
}).ToList());
}
This causes a new problem. Whenever you change tabs, the selection on the combo box is cleared.
MORE EDITS: This question I ran into when uses Rachels answer indicates that a static repository is bad practice because it leaves the DB connection open for the life of the program. I confirmed a connection remains open, but it looks like one remains open for non-static classes too. Here is the repository code:
using (BT8_Entity db = new BT8_Entity())
{
_companies = (from x in db.Companies where x.CO_INACTIVE == 0 select x).ToList();
_customers = (from x in db.Customers where x.CM_INACTIVE == 0 orderby x.CM_FULL_NAME select x).ToList();
_locations = (from x in db.Locations where x.LC_INACTIVE == 0 select x).ToList();
_departments = (from x in db.Departments where x.DP_INACTIVE == 0 select x).ToList();
_users = (from x in db.Users where x.US_INACTIVE == 0 select x).ToList();
}
_companies.Add(new Company { CO_COMPANY_ID = 0, CO_COMPANY_NAME = "" });
_companies.OrderBy(x => x.CO_COMPANY_NAME);
_departments.Add(new Department { DP_DEPARTMENT_ID = 0, DP_DEPARTMENT_NAME = "" });
_locations.Add(new Location { LC_LOCATION_ID = 0, LC_LOCATION_NAME = "" });
However, now I am back to the ugly code above which does not seem a good solution to copying the collection, as the Customer object needs to be manually recreated property by property in any code that needs its. It seems like this should be a very common thing to do, re-using lists, I feel like it should have a solution.