PDA

View Full Version : دیتاگریدی که سه سطر داشته باشه



arash ahmadi
جمعه 06 مهر 1386, 09:20 صبح
با سلام. ایا میشه یک دیتا گرید ویو در برنامه ایجاد کرد که فقط 3 سطر داشته باشه. هر سطر هم مربوط به یک جدول از بانک باشه(یعنی سطر یک مربوط به جدول 1و سطر دوم مربوط به جدول 2 و سطر سوم هم مربوط به جدول 3) و ضمنا" کاربر یک کد(این کد در هر سه جدل وجود داره) رو از کمبو انتخاب می کنه و این دیتاگرید نمایش داده شود؟ اگه ممکنه مثال بزنید.
سوال دوم: چگونه میشه دیتاگرید ویو رو در یک لیست باکس قرارداد. من این کار رو کردم. اما موقع اجرا , لیست باکس خالی نشون می ده.

arash ahmadi
جمعه 06 مهر 1386, 20:00 عصر
کسی نمی تونه کمک کنه ؟

PC2st
جمعه 06 مهر 1386, 22:30 عصر
هر سوال در یک تاپیک... :لبخند:

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

arash ahmadi
شنبه 07 مهر 1386, 07:37 صبح
منظورم این بود که من سه تا جدول دارم. جدول اول اعتبارات است. جدول دوم سایر موارد. یعنی عنوان فیلدها مشترک است. تیتر کل این دیتاگرید یکی است. اما هر سطر هم فقط یک لیبل (مثلا" سطر یک (لیبل اعتبار) یا سطر دو (لیبل سایر موارد) و سطر سوم هم جمع کل موارد است.ابتدا از سه تا دیتاگرید استفاده کردم . هدر اولی رو فعال و بقیه رو غیر فعال کردم.اما مشکل اینه که نمیشه عرض ستونها رو تغییر داد. به همین دلیل خواستم از یک دیتا گریدی که این ویژگی رو داشته باشه استفاده کنم.ایا همچین دیتاگریدی میشه ایجاد کرد؟؟؟.توی نرم افزارهای دیگه (مخصوصا" حسابداری خیلی دیدم که از این دیتاگریدها استفاده میشه.)

MShirzadi
شنبه 07 مهر 1386, 08:16 صبح
من سئوالت رو خوب متوجه نشدم
ولی اگر می خوای Data های مربوط به سه جدول رو در یک DataGrid نشون بدی می تونی از Join کردن Table ها استفاده کنی اگر سئوالت چیزی غیر از اینه و مطمئن هستی که این شکلی حل نمی شه می تونی مطلب رو واضح تر عنوان کنی و همچنین چند تا عکس در رابطه با منظورت بذاری هم بد نیست
بای

PC2st
شنبه 07 مهر 1386, 19:50 عصر
این نوع دیتاگریدی که لازم دارید تا هر سطر مربوط به یک جدول باشه، فکر نمیکنم بشه با dataGridView چنین کاری کرد، اما میتونید اطلاعات جداول رو خودتون در یک dataTable بریزید مثلا مجموع ستون Price از یک جدول رو محاسبه کنید و در یک سطر از dataTable بریزید و مجموع ستون Price از جدول دیگر هم محاسبه کنید و در یک سطر دیگر ریخته و ...

برای گرفتن مجموع سطرهای یک ستون از یک جدول در دیتاتیبل:


long total = (long)ds.Tables[0].Compute("SUM(Price)", "");

که مجموع سطرهای ستون Price از جدول [ds.Tables[0 در متغیر total ریخته میشه.
شما میتوانید متغیر total رو به یک سطر از dataTable ای اضافه کنید.

همچنین میتوانید یک User Control ایجاد کنید و بجای dataGridView ازش استفاده کنید (کمی زمانبر است!)

arash ahmadi
یک شنبه 08 مهر 1386, 20:28 عصر
با سلام. ممنون که راهنمایی کردین . اما من در محاسبه مشکل ندارم.

من قبلا" طبق شکل زیر اطلاعات را ثبت کردم(داخل تکست باکس های فایل ضمیمه)
. محاسبه هم نیز انجام داده ام(از طریق دستور کرسر در sql). مشکل من اینه که حالا می خوام به جای اینکه از تکست باکس استفاده کنم و اطلاعات رو نمایش بدم. از دیتاگرید استفاده کنم.ایا راهی برای اینکه دیتاگرید شامل 3 سطر باشه و اطلاعات 2 جدول رو نمایش بده , هست. ضمنا" امکان ویرایش هم داشته باشه.
توضیح بیشتر برای فایل ضمیمه شده: سطر اول مجموع رو نمایش میده که همانطور که گفتم قبلا" محاسبه شده. سطر دوم اطلاعات درآمد عمومی (جدول 1)رو نشون می ده. سطر 3 (جدول 2)هم اطلاعات سایر موارد رو نشون می ده. ممنون می شم اگه راهنمایی کنید که چکار باید انجام بدهم؟

PC2st
یک شنبه 08 مهر 1386, 21:11 عصر
آیا این TextBox ها به یک منبع داده Bind (متصل) شدند (مثلا یک دیتاتیبل)؟ یا فقط برای نمایش مقادیر از TextBox ها استفاده کردید؟

در هر صورت اگر TextBox ها به هیچی Bind نشدند، اگر میخوای که بجای TextBox ها از یک DataGridView استفاده کنی، میشه توسط خواص Rows و Columns از DataGridView، سطر و ستونها رو در دیتاگریدویو ایجاد کنید (مثلا آخرین ستون هم باید از نوع DataGridViewButtonColumn باشه تا یک Button رو در آخرین سلول از دیتاگریدویو نمایش بده). البته در صورتی میشه این کار رو کرد که اطلاعات DataGridView به منبع داده ای متصل نباشه، یعنی مثلا از خاصیت DataSource استفاده نکرده باشید. آیا این کار رو میخواید انجام بدید؟

arash ahmadi
یک شنبه 08 مهر 1386, 21:37 عصر
بله همین کار رو می خوام انجام بدهم.تکست باکس ها هم برای ورود اطلاعات استفاده کردم .حالا می خام اطلاعات رو در دیتاگرید نمایش بدهم؟؟ اگه ممکنه میشه کدش رو برام بگذارین؟؟.این راهی که شما می گین برای ویرایش اطلاعات هم در داخل دیتاگریدویو کار می کنه. یا نه؟ بازم ممنون

PC2st
یک شنبه 08 مهر 1386, 22:42 عصر
یک سولوشن بنام WindowsApplication1 ایجاد کنید و کدهای زیر رو در فرم Form1 کپی/پیست کنید:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
DataGridView dgv = new DataGridView();

public Form1()
{
InitializeComponent();

DataGridViewTextBoxColumn labelColumn = new DataGridViewTextBoxColumn();
DataGridViewButtonColumn buttonColumn = new DataGridViewButtonColumn();

labelColumn.ReadOnly = true;
labelColumn.Name = "ProvideValidatingResources";
labelColumn.HeaderText = "منابع تأمین اعتبار";
labelColumn.DefaultCellStyle.BackColor = Color.Silver;

buttonColumn.Name = "Total";
buttonColumn.HeaderText = "جمع کل";
buttonColumn.UseColumnTextForButtonValue = true;
buttonColumn.Text = "جمع سطر";

dgv.RightToLeft = RightToLeft.Yes;
dgv.AllowUserToAddRows = false;
dgv.AllowUserToDeleteRows = false;
dgv.AllowUserToOrderColumns = false;
dgv.AllowUserToResizeRows = false;
dgv.Font = new Font("Tahoma", 8, GraphicsUnit.Point);
dgv.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
dgv.EnableHeadersVisualStyles = false;
dgv.ColumnHeadersDefaultCellStyle.BackColor = Color.Silver;
dgv.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizin g;
dgv.RowHeadersWidth = 4;
dgv.MultiSelect = false;

dgv.Columns.Add(labelColumn);
dgv.Columns.Add("BeforThirdProgram", "قبل از برنامه سوم");
dgv.Columns.Add("ThirdProgram", "برنامه سوم");
dgv.Columns.Add("Year86", "مصوب 86");
dgv.Columns.Add("SUM", "جمع");
dgv.Columns.Add(buttonColumn);

dgv.Rows.Add("جمع");
dgv.Rows.Add("درآمد عمومی");
dgv.Rows.Add("سایر منابع");

this.Controls.Add(dgv);

dgv.CellContentClick += new DataGridViewCellEventHandler(dgv_CellContentClick) ;
}

void dgv_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
Console.Beep(e.RowIndex * 500 + 37, 100);
}
}
}

روی دکمه هایی که در دیتاگریدویو هستند، کلیک کنید... هر کدام یک صدای بخصوص میده، از این جهت این کار رو کردم تا ببینید که در رویداد CellContentClick توسط خاصیت e.RowIndex میشه به ایندکس سطر هم پی برد و بعد از کلیک روی هر Button عملیات لازم رو اجرا کرد.

در زمان اجرا میتونید به تک تک سلولهای های dgv دسترسی داشته باشید:


dgv[columnIndex, rowIndex].Value

hassan razavi
یک شنبه 08 مهر 1386, 22:57 عصر
اگر بانک شما SQL Server باشه به راحتی می تونید با Store Procedure اینکار رو انجام بدید.
به شرطی که فیلدهای خروجی برای هر 3 جدول یکی باشه.
مثلا از هر 3 تا جدول ، نام ، تلفن و آدرس بخواهید بگیرید

یه Store Procedure در بانک بسازید و با 3 تا Select نتایج را به راحتی برگردانید.
یک پارامتر هم برای شرط میزارید برا Store Procedure

PC2st
سه شنبه 10 مهر 1386, 21:57 عصر
پس با این توضیحات، آیا TextBox ها به یک منبع داده متصل نیستند؟ یعنی با دادن "کد پروژه" و کلیک روی دکمه "نمایش اطلاعات"، مقادیر از بانک اطلاعاتی خوانده میشود و در TextBox ها ریخته میشود؟ یا اینکه مقادیر موجود در بانک اطلاعاتی را درون یک DataTable ریخته اید و با گرفتن "کد پروژه" اطلاعات را از آن DataTable استخراج میکنید؟ بعبارت دیگر، TextBox ها به یک منبع داده (مثل DataTable یا DataSet) متصل (Bind) شده اند؟ اگر متصل نشده باشند، یعنی اینکه با کلیک روی دکمه "نمایش اطلاعات" TextBox ها رو مقدار دهی میکنید (بصورت دستی) پس به همین صورت میتوانید سلولهای DataGridView را هم مقدار دهی کنید. یعنی بعد از کلیک روی دکمه "نمایش اطلاعات" تک تک سلولها رو مقدار دهی کنید. بنظر هنوز کامل متوجه نشدم، اگر امکانش هست، کمی بیشتر توضیح دهید...

arash ahmadi
سه شنبه 10 مهر 1386, 22:54 عصر
همانطور که گفتم ,من اون تکست باکس ها رو برای اضافه کردن اطلاعات از کاربر با با استفاده از پروسیجری که کد پروژه رو می گیره طراحی کردم.( یعنی اطلاعات رو با پروسیجر بانک insertکردم). حالا می خوام کاربر با وارد کردن کد پروژه اطلاعات مربوط به اون کد رو در گرید ویو مشاهده کنه ( امکان ویرایش هم به او بدهم.) اما نمی دونستم که چطوری اون سه سطر(فقط 3 سطر, طبق فایل ضمیمه که مربوط به 2 جدول است) رو در گرید ویو نشون بدم؟ دلیل کارم هم اینه که برای نمایش اطلاعات مرتبط با کد پروژه (اگه بخوام از همون تکست باکس ها استفاده کنم , برای هر ستون (فیلد) باید از دیتا ریدر استفاده کنم. که مدیریت این کار با توجه به تعداد زیاد تکست باکس ها خیلی سخته. بنابر این خواستم همین کار رو با یک دیتاگرید ویو انجام بدم؟ به نظر شما کار من اشتباه است؟ اگه ممکنه راهنمایی کنید.

PC2st
چهارشنبه 11 مهر 1386, 00:03 صبح
برای خواندن اطلاعات از DataReader استفاده میکنید و برای آپدیت بانک اطلاعاتی از یک Stored Procedure. پس TextBox ها به منبع داده متصل نشده اند... بنابراین همان کدهایی که نوشته بودم رو میتونید بکار ببرید، مشکل از کجاست؟
از سلولهای دیتاگریدویو مثل یک TextBox استفاده کنید و مقادیری که از DataReader گرفته شده رو در سلولهای دیتاگریدویو قرار دهید. بعد از این که کاربر داده ها را ویرایش کرد یا حتی اطلاعات جدیدی اضافه کرد، میتوانید مقادیر موجود در سلولهای دیتاگریدویو رو بصورت تک تک خوانده و در دیتابیس ذخیره کنید (بوسیله متد ExecuteNonQuery از شیئ Command).


به نظر شما کار من اشتباه است؟ اگه ممکنه راهنمایی کنید.
روش اشتباهی به نظر نمیرسه... اما روشهای مختلفی رو میشه انجام داد.
مثلا اگر مقدار مربوط به "کد پروژه" در واقع کاری جز فیلتر کردن اطلاعات جداول نداره، پس بهتره که کل اطلاعات هر جدول رو در یک DataTable (یا DataSet) ریخته و توسط مقدار "کد پروژه" عملیات فیلتر سازی رو روی DataTable ها انجام بدید و همچنین TextBox ها رو به DataTable ها وصل کنید و ...
اصولا دیتاگریدویو بصورت فیلدی عمل میکنه، یعنی اینکه هر فیلد میتونه مربوط به یک جدول باشه، ولی در این برنامه ای که شما لازم دارید، هر فیلد به یک جدول مربوط نیست و در واقع هر سطره که به یک جدول مرتبط شده! اگر کار با TextBox ها براتون جالب نیست (چون هر TextBox رو میشه منحصرا به یک منبع داده متصل کرد برخلاف سلولهای دیتاگریدویو)، میتونید یک User Control برای این TextBox ها ایجاد کنید و برنامه اصلی رو از کدهای آشفته ای که برای متصل کردن داده ها به TextBox بکار رفته، پنهان سازید...
مثال میزنم، اگر جداولی دارید که این جداول حاوی یک فیلد مربوط به "کد پروژه" هست، خب یک راه مناسب اینه که این جداول رو بطور کامل در یک DataTable ذخیره کنید (توسط متد Fill از شیئ دیتاآداپتر)، سپس یک User Control بسازید که نمایی شبیه به همان عکسی رو داشته باشه که ضمیمه کردید، سپس این User Control میتونه به شکل زیر مورد استفاده قرار بگیره (اگر نام User COntrol بصورت MyUserControl باشه):


MyUserControl muc=new MyUserCOntrol();
muc.DataSource1 = dt1;
muc.DataSource2 = dt2;
muc.CurrentProjectCode = 1275;

به کدهای بالا اگر دقت کنید، ایجاد این User COntrol باعث افزایش صفت Encapsulation در برنامه شده، بعبارتی مانع از آشفتگی برنامه میشه (چون برنامه اصلی مثلا فرم Form1 از جزئیات کار TextBoxها و نحوه اتصال به آنها باخبر نیست و Form1 فقط منابع dt1 و dt2 رو برای muc مشخص میکنه و کد دیگری در form1 نخواهد بود، چون بقیه کدها در User Control کپسوله شدند). در کدهای فوق، در خط دوم، مثلا منبع داده برای جدول 1 رو مشخص میکنید و در خط بعد، منیع داده برای جدول 2 رو هم مشخص میکنید و در خط بعدی هم کد پروژه رو مشخص میکنید. در اینصورت User Control وظیفه داره که بر اساس منابع dt1 و dt2 اطلاعات رو در TextBox ها نمایش بده. (dt1 و dt2 از نوع DataTable هستند)



در هر صورت اگز نمی خواهید که از یک User Control استفاده و اگر DataReader رو ترجیح میدهید پس نمیتوانید از منابعی همچون dt1 و dt2 برای جداول 1 و 2 استفاده کنید. پس در اینصورت، اگر هم میخواید که از دیتاگریدویو استفاده کنید:
باید از سلولهای دیتاگریدویو مثل یک TextBox استفاده کنید، یعنی همانطور که توسط DataReader یک مقدار را درون TextBox قرار میدهید، به همان صورت آن مقدار را درون یک سلول از دیتاگریدویو قرار دهید.


صرف نظر از توضیحات نه چندان مناسبی که دادم، بهتره که جزئی تر مشکل رو بیان کنید.

اَرژنگ
چهارشنبه 11 مهر 1386, 14:53 عصر
[quote=arash ahmadi]با سلام. عرض تسلیت به مناسبت شهادت امیر المومنین علی (ع)
[quote]

دوست عزیز، وقتی که پست میکنید اگر در پیامتان قسمتی داشته باشید که به زمان بخصوصی ربط داره بعد از مدتی بی معنی میشه. فکر کنید کسانی که این را چند ماه دیگر موقوع تولد حضرت علی (ع) میخوانند چی فکر میکنند.

hdv212
چهارشنبه 11 مهر 1386, 20:53 عصر
arash ahmadi جان اگه سوالتو رو درست متوجه شده باشم (پست اولت)، شما میخوای یک سطر از اطلاعات بازگردانده شده از سه جدول، در سه سطر مجزای یک dataGridView به نمایش در بیاد، خب برای این کار شما باید مطمئن باشی که فیلدهای سه جدولی که میخوای در دیتاگریدت نشون بدی با هم به ترتیب، همنوع باشن.
روش حل این مشکل هم اینه که شما از کلمه ی کلیدی top در query ات استفاده کنی که از هر جدول فقط یه سطر برگردونه، یه چیزی مثل این :

select top 1 * from cutomers
خب الان باید سه تا query این شکلی داشته باشی که از سه تا جدولت اطلاعات میگیره (اونم query ای که فیلدهاشون به ترتیب یا هم همسنگ باشن و تعداشون هم یکی باشه)
پیشنهاد میکنم یه stored procedure بساز و این سه کوئری رو داخل اون بنویس و همه رو با هم union کن، اینطوری :

select top 1 * from tbl_1
union
select top 1 * from tbl_2
union
select top 1 * from tbl_3
و با این sp دیتاستت رو fill کن و دیتاگریدت رو هم به این دیتاست بایند کن.
البته به غیر از دستور union یکی دیگه هم هست که union all نام دارد و من چون متاسفانه sql server management studio ندارم نمیتونم برات تست کنم و دقیق بهت بگم که از کدوما باید استفاده کنی، زحمت این کار رو خودت بکش یا در Books Online در موردشون جستجو کن.