أنا نشر عنصر تحكم DataGridView في نموذج Windows (C # 2.0 لا WPF).
هدفي هو عرض شبكة تملأ بدقة كل ما هو متاح من خلايا - أي مناطق غير مظلمة (رمادية داكنة) أسفل اليمين وأحجام كل عمود بشكل مناسب وفقًا للبيانات التي يحتوي عليها ، لكن يسمح أيضًا للمستخدم بتغيير حجم أي من الأعمدة حسب رغبته.
أحاول تحقيق ذلك عن طريق تعيين AutoSizeMode لكل عمود ليكون DataGridViewAutoSizeColumnMode.AllCells باستثناء أحد الأعمدة التي قمت بتعيينها إلى DataGridViewAutoSizeColumnMode.Fill من أجل ضمان منطقة الشبكة بالكامل مليئة بدقة مع البيانات. (لا أمانع أنه عندما يحاول المستخدم تغيير حجم هذا العمود ، فإنه يعود إلى حجم يضمن استخدام المساحة الأفقية دائمًا.)
ومع ذلك ، كما ذكرت ، بمجرد تحميلها ، أود السماح للمستخدم بتغيير حجم الأعمدة لتناسب متطلباته الخاصة - عند تعيين قيم AutoSizeMode لكل عمود يبدو أن المستخدم غير قادر بعد ذلك على تغيير حجم تلك الأعمدة.
لقد حاولت عدم تعيين AutoSizeMode لجميع الأعمدة التي تسمح بتغيير حجم ولكن لا يحدد الحجم الأولي وفقا للبيانات التي تحتوي عليها الخلايا. تحدث نفس النتيجة عند تغيير AutoSizeMode الخاص بالشبكة مرة أخرى إلى "Not Set" بعد تحميل البيانات.
هل هناك إعداد أفتقده هنا والذي يسمح بالإعداد التلقائي لعرض الأعمدة الافتراضية وحجم المستخدم أو هل هناك طريقة أخرى يجب استخدامها عند تعبئة عنصر التحكم DataGridView؟
هذه الخدعة تعمل لي:
grd.DataSource = DT;
//set autosize mode
grd.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
grd.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
grd.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
//datagrid has calculated it's widths so we can store them
for (int i = 0; i <= grd.Columns.Count - 1; i++) {
//store autosized widths
int colw = grd.Columns[i].Width;
//remove autosizing
grd.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
//set width to calculated by autosize
grd.Columns[i].Width = colw;
}
ما يحدث هنا هو أنك تقوم بتعيين autosize إلى وضع whathever الذي تحتاجه ، ثم تقوم بعد كل عمود بتخزين العرض الذي حصلت عليه من حساب autosize وإزالة autosizing وتعيين العرض على القيمة التي قمت بتخزينها من قبل.
ربما يمكنك الاتصال
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.Fill);
بعد تحديد مصدر البيانات. وسوف تحدد العرض وتسمح بتغيير الحجم.
المزيد عن MSDN طريقة DataGridView.AutoResizeColumns (DataGridViewAutoSizeColumnsMode) .
نسخة C # من كود ميروسلاف زادرافيتش
for (int i = 0; i < dataGridView1.Columns.Count-1; i++)
{
dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
dataGridView1.Columns[dataGridView1.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
int colw = dataGridView1.Columns[i].Width;
dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
dataGridView1.Columns[i].Width = colw;
}
نشر باسم مجتمع ويكي حتى لا يبتعد عن سمعة الآخرين
في طلبي قمت بتعيين
grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
grid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
أيضا ، لقد وضعت
grid.AllowUserToOrderColumns = true;
grid.AllowUserToResizeColumns = true;
الآن يمكن تغيير عرض الأعمدة ويمكن إعادة ترتيب الأعمدة من قبل المستخدم. هذا يعمل بشكل جيد بالنسبة لي.
ربما هذا سوف يعمل من أجلك.
حسنا ، لقد فعلت هذا مثل هذا:
dgvReport.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dgvReport.AutoResizeColumns();
dgvReport.AllowUserToResizeColumns = true;
dgvReport.AllowUserToOrderColumns = true;
في هذا الترتيب بالذات. يتم تغيير حجم الأعمدة (موسعة) ويمكن للمستخدم تغيير حجم الأعمدة بعد ذلك.
بعد إضافة البيانات إلى الشبكة ، أضف الكود التالي الذي سيعدل العمود وفقًا لطول البيانات في كل خلية
dataGrid1.AutoResizeColumns();
dataGrid1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
هنا النتيجة
إذا فهمت السؤال بشكل صحيح ، يجب أن تكون هناك طريقة أسهل لإنجاز ما تحتاجه. اتصل بـ dgvSomeDataGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
الذي عليه أن يقوم بالخدعة. ومع ذلك ، توجد مشكلة واحدة حيث لا يمكنك ببساطة استدعاء هذه الطريقة مباشرة بعد نشر عنصر التحكم DataGridView الخاص بك. بدلاً من ذلك ، سيتعين عليك إضافة EventHandler للحدث VisibleChanged واستدعاء الطريقة هناك.
استئناف السؤال:
اجعل عرض العمود يتكيف مع المحتوى (مع طريقة مختلفة عبر العمود) ،
ولكن بعد ذلك السماح للمستخدم بتعيين عرض العمود ...
تطوير من إجابة Miroslav Zadravec ، بالنسبة لي ما نجح كان على الفور استخدام column.Width
المحسوب تلقائيًا لتعيين ... column.Width
!
foreach (DataGridViewColumn column in dataGridView.Columns)
{
if (/*It's not your special column*/)
{
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
column.Width = column.Width; //This is important, otherwise the following line will nullify your previous command
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.NotSet;
}
}
//Now do the same using Fill instead of AllCells for your special column
يتم اختبار هذا للعمل عندما يتم إنشاء DataGridView
بالفعل ، باستخدام خدعة مثل هذا .
هذا فعل العجائب بالنسبة لي:
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
فيما يلي رمز مبسط لإجابة ميروسلاف زادرافيتش في c #:
CurrentDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader;
for (int i = 0; i < dataGridView1.Columns.Count; i++) dataGridView1.Columns[i].Width = dataGridView1.Columns[i].Width;
CurrentDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
بسيطة سطرين من رمز يعمل بالنسبة لي.
dataGridView.DataSource = dataTable;
dataGridView.AutoResizeColumns();
رمز C # أكثر إتقانًا قليلاً من كود Miroslav Zadravec على افتراض أن جميع الأعمدة يجب أن يتم ضبطها تلقائيًا
for (int i = 0; i < dgvProblems.Columns.Count; i++)
{
dgvProblems.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
int colw = dgvProblems.Columns[i].Width;
dgvProblems.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
dgvProblems.Columns[i].Width = colw;
}
يؤدي هذا إلى ضبط جميع الأعمدة تلقائيًا وفقًا لمحتواها ، ويملأ المساحة الفارغة المتبقية عن طريق مد عمود محدد ويمنع سلوك "القفز" عن طريق تعيين العمود الأخير لملء أي تغيير حجم في المستقبل.
// autosize all columns according to their content
dgv.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
// make column 1 (or whatever) fill the empty space
dgv.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
// remove column 1 autosizing to prevent 'jumping' behaviour
dgv.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
// let the last column fill the empty space when the grid or any column is resized (more natural/expected behaviour)
dgv.Columns.GetLastColumn(DataGridViewElementStates.None, DataGridViewElementStates.None).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
نسخة أخرى من كود ميروسلاف زادرافيتش ، ولكنها أكثر آلية وعالمية قليلاً:
public Form1()
{
InitializeComponent();
dataGridView1.DataSource = source;
for (int i = 0; i < dataGridView1.Columns.Count - 1; i++) {
dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
dataGridView1.Columns[dataGridView1.Columns.Count].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
void Form1Shown(object sender, EventArgs e)
{
for ( int i = 0; i < dataGridView1.Columns.Count; i++ )
{
int colw = dataGridView1.Columns[i].Width;
dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
dataGridView1.Columns[i].Width = colw;
}
}
لقد وضعت الجزء الثاني في حدث منفصل ، لأنني ملأت datagridvew
في تهيئة النموذج ، وإذا كان كلا الجزأين هناك ، فلا شيء يتغير ، لأنه من المحتمل أن يقوم autosize بحساب العروض بعد عرض datagridview
، لذلك فإن العروض لا تزال الافتراضية في طريقة Form1()
. بعد الانتهاء من هذه الطريقة ، تقوم ميزة autosize بالخداع ، وبعد ذلك مباشرة (عند عرض النموذج) ، يمكننا ضبط العروض حسب الجزء الثاني من الكود (هنا في Form1Shown
event). هذا يعمل بالنسبة لي مثل السحر.
dataGridView1.AutoResizeColumns ()؛
يتم عرض أعمدة الأعمدة لتناسب محتواها وقد استخدمت بيان رفع الصوت عالياً ، لقد حل مشكلتي.
الخطوة الأولى :
RadGridViewName.AutoSize = true;
الخطوة الثانية :
// This mode fit in the header text and column data for all visible rows.
this.grdSpec.MasterTemplate.BestFitColumns();
خطوة ثالثة :
for (int i = 0; i < grdSpec.Columns.Count; i++)
{
// The column width adjusts to fit the contents all cells in the control.
grdSpec.Columns[i].AutoSizeMode = BestFitColumnMode.AllCells;
}
تحسن طفيف من نسخة شنابل
int nLastColumn = dgv.Columns.Count - 1;
for (int i = 0; i < dgv.Columns.Count; i++)
{
if (nLastColumn == i)
{
dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
else
{
dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
}
for (int i = 0; i < dgv.Columns.Count; i++)
{
int colw = dgv.Columns[i].Width;
dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
dgv.Columns[i].Width = colw;
}
هل حاولت إعداد خاصية FillWeight
لكائن DataGridViewColumns
؟
فمثلا:
this.grid1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
this.grid1.Columns[0].FillWeight = 1.5;
أعتقد أنه يجب أن تعمل في قضيتك.
DataGridView.Columns
، قم بتغيير AutoSizeMode
إلى واحد صالح ، اجمع قيمة العرض وأعده بعد التغيير AutoSizeMode
إلى DataGridViewAutoSizeColumnMode.None
).Form.Show()
أو Form.ShowDialog()
. لذلك وضعت مقتطف الشفرة في الحدث Form.Shown
وهذا يناسبني.الكود الذي قمت بتحويله ، بغض النظر عن أي DataGridView.AutoSizeColumnsMode
الذي تم تعيينه من قبل ، أستخدم DataGridViewColumn.GetPreferredWidth()
بدلاً من تغيير DataGridViewColumn.AutoSizeMode
وأعد قيمة العرض على الفور ، ثم غير DataGridView.AutoSizeColumnsMode
مرة واحدة:
private void form_Shown(object sender, EventArgs e)
{
foreach (DataGridViewColumn c in dataGridView.Columns)
c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.DisplayedCells, true);
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
}
تأكد من ضبط
dataGridView.AllowUserToResizeColumns = true;
لا أعرف كيف يعمل هذا فقط بعد عرض النموذج.
اضطررت للقيام بذلك في VB وأفضّل تقسيمه إلى طريقة وضعت في وحدة نمطية. يمكنك إضافة عمود التعبئة كمعلمة ByRef أخرى إذا كنت ترغب في ذلك.
''' <summary>
''' Makes all columns in a DataGridView autosize based on displayed cells,
''' while leaving the column widths user-adjustable.
''' </summary>
''' <param name="dgv">A DataGridView to adjust</param>
Friend Sub MakeAdjustableAutoSizedGridCols(ByRef dgv As DataGridView)
Dim width As Integer
For Each col As DataGridViewColumn In dgv.Columns
col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells
width = col.Width
col.AutoSizeMode = DataGridViewAutoSizeColumnMode.None
col.Width = width
Next
dgv.AllowUserToResizeColumns = True
End Sub
foreach (DataGridViewColumn c in dataGridView.Columns)
c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true);
يجب أن يعمل هذا سواء تم عرض dataGridView
أم لا (أي حتى إذا تم استدعاؤه من مُنشئ الفصل الدراسي).
الطريقة نفسها ، ولكن مع DataGridViewAutoSizeColumnMode.DisplayedCells
، تفشل في الحالة المذكورة أعلاه للسبب الواضح - لم يتم عرض أي خلية حتى الآن! لسبب غير واضح ، فشل AutoResizeColumns
أيضًا في هذه الحالة.
يمكنك فعل شيء مثل هذا:
grd.DataSource = getDataSource();
if (grd.ColumnCount > 1)
{
for (int i = 0; i < grd.ColumnCount-1; i++)
grd.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
grd.Columns[grd.ColumnCount-1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
if (grd.ColumnCount==1)
grd.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
جميع الأعمدة سوف تتكيف مع المحتوى باستثناء آخر واحد سوف تملأ الشبكة.
إذا قمت بربط مصدر البيانات الخاص بك بملف البيانات على سبيل المثال ، فأنت بحاجة إلى تعيين الخصائص بعد الانتهاء من الربط:
private void dgv_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dgv.AutoResizeColumns();
dgv.AllowUserToResizeColumns = true;
}