PDA

View Full Version : سوال: پر کردن ObservableCollection در MVVM



water_lily_2012
دوشنبه 12 فروردین 1392, 10:00 صبح
سلام
من در معماری MVVM می خواهم یک دیتاگرید را با استفاده از خروجی دستور Linq پر کنم اما چند تا چیز را نمی دونم.:متفکر:

فکر کنم باید یک پراپرتی از نوع ObservableCollection داشته باشم!
1. خوب حالا دستور لینک را در کجا بنویسم؟ در لایه Model و یا در ViewModel.
2. خروجی دستور لینک را چگونه به ObservableCollection تبدیل کنم. یعنی تنها راهش استفاده از Foreach هست و Add کردن هر سطر در Collection.:متعجب:

من با پر کردن و بایند یک شی مثل TextBox مشکلی ندارم ولی بایند دیتاگرید را درک نمی کنم.:گریه:
خواهشاً یکی راهنمایی کنه. این بایند دیتاگرید را در Model و ViewModel شرح بدهید.
تشکر.:خجالت:

aghayex
دوشنبه 12 فروردین 1392, 14:02 عصر
private ObservableCollection _dt;
public ObservableCollection dt
{
get {retyrn _dt;}
private set
{
if(object.refrenceequals(_dt,value)!=true)
{
_dt=value;
propetycheng("dt");
}
}

این از پروپرتی حالا اگه از ef استفاده می کنی وقتی کوئریتو نوشتی به صورت زیر در ObservableCollection می ریزیش :


_dt=new ObservableCollection (query.tolist());

اینو ذهنی نوشتم ممکنه در استفاده از لغات مشکل داشته باشه اگه نیاز بود بگو تا راهنماییت کنم

water_lily_2012
دوشنبه 12 فروردین 1392, 14:35 عصر
سلام
تشکر از پاسختون
راستش مگه نباید Collection به صورت زیر تعریف شود. یعنی بر اساس یک کلاس:

public ObservableCollection<Mission> Empdata
{
get;
private set;
}

خوب حالا اگر اینطور تعریف شود بازهم به همان صورت باید پر شود.یعنی

Empdata=new ObservableCollection (query.tolist());

بعد یک نکته مهم اینکه در Model باید Collection را پر کرد و یا در ViewModel ؟؟؟

الان این را نوشتم ولی در تبدیل دو نوع به همدیگر خطا میده .

public DataItem()
{

var data = db.SpMissionSellAll("1391/09/01", "1391/12/01");
_Empdata = new ObservableCollection<Mission> (data.ToList());
}

LqDataDataContext db = new LqDataDataContext();
private ObservableCollection<Mission> _Empdata;

public ObservableCollection<Mission> Empdata
{
get { return _Empdata; }
private set;
}

aghayex
دوشنبه 12 فروردین 1392, 17:42 عصر
public DataItem()
{

var data = db.SpMissionSellAll("1391/09/01", "1391/12/01");
Empdata = new ObservableCollection<Mission> (data.ToList());
}

LqDataDataContext db = new LqDataDataContext();
private ObservableCollection<Mission> _Empdata;

public ObservableCollection<Mission> Empdata
{
get { return _Empdata; }
private set;
}



این کامل تر هست و اگه بتونی دستور ست اونو هم مثل مال من بنویسی بهتره.

یه مشکل داشتی که چرا موقعی من ObservableCollection رو پر میکنم اما چیزی نمی بینم به دلیل اینکه شما شی ObservableCollection رو پر می کنی نه پروپرتی و دومین دلیلش هم استفاده نکردن از شی raisepropertycheng("Empdata"); هست که اونو در بخش ست می نویسی تا برنامه خبر داشته باشه شما شی Empdata رو تغییر دادید
model محل نگه داری کلاس هایی هست که دیتابیس رو شبیه سازی کرده که اگه بخوام مثال بزنم همون مدل EF که از دیتابیس درست می کنید یه مدل هست و دستورات و کوئری ها رو در vie model می نویسن
در خصوص سوالتون که پرسیده بودی شی ObservableCollection رو باید به صورت ObservableCollection<Mission> تعریف کنید حرفتون درسته و اون عبارتی که شما می نویسید یا یه کلاس از نوع notifycationproerty باشه یا یه تیبل از نوع جداولت .
وقتی شما تمام جدول رو می خواهید واکشی کنید و در ObservableCollection بریزی به این صورت عمل می کنی ObservableCollection<entities.table1> , entities همون مدلت هست و table1 هم نام تیبلت هست .
اما در بیشتر مواقع ما تعداد محدودی از جدولمون رو در ObservableCollection می ریزیم که در این حالت فرضا شما دو ستون id و code رو می خواهی واکشی کنی ابتدا کلاسی از نوع notifycationproerty ( اگه درست نوشته باشم ) با دو خصیه id و code بعدش دیگه نام این کلاس رو جلوی ObservableCollection می نویسیم مثل ObservableCollection <newmisson> و در بخش کوئری هم باید به صورت زیر عمل کنی :

var data = from a in db.table1 where شرط مورد نظرت select new newmisson{ id=a.id,code=a.code}

water_lily_2012
دوشنبه 12 فروردین 1392, 19:33 عصر
سلام
دوست عزیز یک مشکل در تبدیل هست.
ببینید این کلاس من:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace MissionTelecomSystem.Model
{
public class CityModel : INotifyPropertyChanged
{
private int _CityCode;
public int CityCode
{
get { return _CityCode; }
set
{
_CityCode = value;
OnPropertyChanged("CityCode");
}
}
private string _CityName;
public string CityName
{
get { return _CityName; }
set
{
_CityName = value;
OnPropertyChanged("CityName");
}
}
private string _CityDis;
public string CityDis
{
get { return _CityDis; }
set
{
_CityDis = value;
OnPropertyChanged("CityDis");
}
}

public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyname)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyname));
}
}
}


این هم کد و پراپرتی :


var data = from u in db.Cities select u;
Empdata=new ObservableCollection<CityModel> (data.ToList());


private ObservableCollection<CityModel> _empdata = new ObservableCollection<CityModel>();
public ObservableCollection<CityModel> Empdata
{
get { return _empdata; }
set
{
_empdata = value;
OnPropertyChanged("Empdata");
}
}


این هم خطا:

Error 3 Argument 1: cannot convert from 'System.Collections.Generic.List<MissionTelecomSystem.Data.City>' to 'System.Collections.Generic.List<MissionTelecomSystem.Model.CityModel>' C:\REZA\Projects\Project's\MissionTelecomSystem\Mi ssionTelecomSystem - Copy\MissionTelecomSystem\ViewModel\MainViewModel. cs 71 66 MissionTelecomSystem

Error 2 The best overloaded method match for 'System.Collections.ObjectModel.ObservableCollecti on<MissionTelecomSystem.Model.CityModel>.ObservableCollection(System.Collections.Generic.L ist<MissionTelecomSystem.Model.CityModel>)' has some invalid arguments C:\REZA\Projects\Project's\MissionTelecomSystem\Mi ssionTelecomSystem - Copy\MissionTelecomSystem\ViewModel\MainViewModel. cs 71 29 MissionTelecomSystem

aghayex
سه شنبه 13 فروردین 1392, 01:19 صبح
اول اینو اینطور بنویس

private ObservableCollection<CityModel> _empdata ;


دوم کوئریتو به صورت زیر بنویس :

var data = from u in db.Cities select new CityModel{CityCode=u.CityCode,CityName=u.CityName, CityDis=u.CityDis};;

water_lily_2012
سه شنبه 13 فروردین 1392, 09:47 صبح
سلام

بازهم تشکر .:خجالت:


اما چند سوال:
1. وقتی از کلاس لینک استفاده می کنم خودش کلاس پراپرتی جدول را تولید می کنه. خوب چرا من دوباره یکی دیگه تعریف کنم. فرقی با هم دیگر دارند؟؟:متفکر:
بهتر نیست از همان استفاده کنم.

حالا با استفاده از کلاس تعریف شده خود لینک کد به صورت زیر شد:

MissionDataClassesDataContext db = new MissionDataClassesDataContext();

public MainViewModel()
{
var data = from u in db.Cities select u;
Empdata = new ObservableCollection<City>(data);

/*foreach (var city in data)
{
Empdata.Add(city);
OnPropertyChanged("Empdata");
}*/
}


private ObservableCollection<City> _empdata;
public ObservableCollection<City> Empdata
{
get { return _empdata; }
set
{
_empdata = value;
OnPropertyChanged("Empdata");
}
}

سوال دوم :
اگر با کلیک روی سلول های دیتاگرید بخواهم اطلاعاتی را اضافه و یا ویرایش کنم خوب چگونه در جدول باید ذخیره کنم.:ناراحت:
اصلا برنامه از کجا متوجه تغییرات می شود. خواهشاً کامل توضیح دهید.:لبخندساده:

aghayex
سه شنبه 13 فروردین 1392, 23:01 عصر
در مورد سوال اول در همون پست به طور مفصل توضیح دادم . وقتی شما می خواهی کل جدول رو فراخوانی کنی یعنی تمام ستون های جدول رو فراخوانی کنی دیه نیاز نیست بری کلاس بسازی و در جلوی ObservableCollection نام جدول تو می نویسی که EF تولید کرده و کلاس نویسی برا مواقعی هست که شما می خواهی تعداد محدودی از ستون های تیبل رو داشته باشی

در خصوص سوال اون خیلی وقت می برده شما یه نمونه بده تا تغیرات مورد نظر رو روش بدم

water_lily_2012
چهارشنبه 14 فروردین 1392, 11:38 صبح
سلام
بازهم تشکر
یک سوال دارم. اگر از کلاس خود لینک استفاده کنم ذخیره در دیتابیس و دیتاگرید به این صورت هست.

City city = new City();
city.CtCode = 410;
city.CtName = "اصفهان";
Empdata.Add(city);
db.Cities.InsertOnSubmit(city);
db.SubmitChanges();

حالا اگر از کلاس جدید استفاده کنم ذخیره در دیتاگرید و دیتابیس به چه صورت میشه.

و یک سوال مهمتر : اگر چند جدول داشته باشم و بخواهم از هر کدام تعدادی ستون را در دیتاگرید نمایش دهم چه کار کنم. کلاس به چه صورت تعریف می شود.
تشکر