1

私は 2 つの DataGridViewComboBoxColumn を持っています。最初の GridViewComboBoxColumn の選択に従って 2 番目の列を埋めたいと思います。最初のコンボボックスにグループがあり、2 番目のコンボボックスにサービスがあります。グループ1を選択すると、グループ1のサービスのみがサービスコンボボックスに表示されます。私はストアドプロシージャを使用しています。

var groupColumn = new DataGridViewComboBoxColumn();

                DataTable dtcategori = cb.GetAllDataCategori();
                groupColumn.Name = "Group";
                groupColumn.HeaderText = Resources.GroupName;
                groupColumn.DataSource = dtcategori;
                groupColumn.ValueMember = "ID";
                groupColumn.DisplayMember = "Name";
                groupColumn.Width = 100;
                this.DataGridViewFactor.Columns.Add(groupColumn);

                var serviceColumn = new DataGridViewComboBoxColumn();
                    //var categoriId = Convert.ToInt32(groupColumn.);
                // DataTable dtServices = sb.ServiceGetById(categoriId);
                    DataTable dtServices = sb.GetAllDataServices();
                    serviceColumn.Name = "Services";
                    serviceColumn.HeaderText = Resources.Service;
                    serviceColumn.DataSource = dtServices;
                    serviceColumn.ValueMember = "ID";
                    serviceColumn.DisplayMember = "Name";
                    serviceColumn.Width = 100;

                    this.DataGridViewFactor.Columns.Add(serviceColumn);
4

1 に答える 1

1

うわー、この答えを見つけるのに約2時間かかりました。よくありませんが、使用可能で役に立ちます:)

のコンボボックスから項目を選択したときに通知するイベントが必要なため、最初に、コード内groupColumn.DataSourceの aをBindingSourcenot aに変更する必要があります。イベントがないことがわかります。次に、との間に関係が見当たりません。 のデータソースには のようなフィールドが必要です。これにより、2 つの列をリンクできます。そういう分野もあると思います。あなたには がありますが、それがかどうかはわかりません。あなたの かもしれません。DataTablePositionChangedgroupColumnDataGridViewColumnSelectedIndexChangedGroupServicesServicesGroupIDGroupIDServicesIDGroupIDServiceID

groupColumn's推奨: andserviceColumn's DisplayStyleを変更する必要があると思いますDataGridViewComboBoxDisplayStyle.Nothing - 私には最適です。

コードの横のコメントで私の解決策を説明したいと思います。コードは次のとおりです。

//Your code is modified a little.
var groupColumn = new DataGridViewComboBoxColumn();
groupColumn.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
DataTable dtcategori = cb.GetAllDataCategori();
groupColumn.Name = "Group";
groupColumn.HeaderText = Resources.GroupName;
//Create a BindingSource from your DataTable
BindingSource bs = new BindingSource(dtcategori,"");
groupColumn.DataSource = bs;
bs.PositionChanged += (s,e) => {
   //Filter for items which have the selected GroupID
   ((DataTable)((DataGridViewComboBoxColumn)DataGridViewFactor.Columns["Services"]).DataSource).DefaultView.RowFilter =
                string.Format("GroupID='{0}'",((DataRowView)bs.Current).Row["ID"]);
   //Set the initial value of the corresponding cell in serviceColumn
   DataGridViewFactor.CurrentRow.Cells["Services"].Value = ((DataTable)((DataGridViewComboBoxColumn)DataGridViewFactor.Columns["Services"]).DataSource).DefaultView.ToTable().Rows[0]["Name"];
};
//-------------------------------------------
groupColumn.ValueMember = "ID";
groupColumn.DisplayMember = "Name";
groupColumn.Width = 100;
this.DataGridViewFactor.Columns.Add(groupColumn);

var serviceColumn = new DataGridViewComboBoxColumn();
serviceColumn.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
//var categoriId = Convert.ToInt32(groupColumn.);
// DataTable dtServices = sb.ServiceGetById(categoriId);
DataTable dtServices = sb.GetAllDataServices();
serviceColumn.Name = "Services";
serviceColumn.HeaderText = Resources.Service;
serviceColumn.DataSource = dtServices;
serviceColumn.ValueMember = "ID";
serviceColumn.DisplayMember = "Name";
serviceColumn.Width = 100;

this.DataGridViewFactor.Columns.Add(serviceColumn);

//Because filtering this way can make some cell have a value which is not contained in 
//the DataGridViewComboBoxColumn.Items, we have to handle the DataError
private void DataGridViewFactor_DataError(object sender, DataGridViewDataErrorEventArgs e){
    //We're interested only in DataGridViewComboBoxColumn
    if(DataGridViewFactor.Columns[e.ColumnIndex] is DataGridViewComboBoxColumn){
        e.Cancel = true;
    }
}
//Because when you filter on a row, the DataGridViewComboBoxColumn.DataSource with
//the filtered DefaultView will apply on all the rows in the same 
//DataGridViewComboBoxColumn, we have to apply the filter for each row if it is selected
private void DataGridViewFactor_SelectionChanged(object sender, EventArgs e)
{            
        ((DataTable)((DataGridViewComboBoxColumn)DataGridViewFactor.Columns["Services"]).DataSource).DefaultView.RowFilter =
           string.Format("GroupID='{0}'", DataGridViewFactor.CurrentRow.Cells["Group"].Value);            
}
//Because when you filter on a row, the DataSource DefaultView of the groupColumn will
//be changed (limited to fewer items) and there will be cells in that column having 
//values which are not contained in the filtered items. Those cells will not be 
//displayed when you move the mouse over. This CellPainting event handler is to help 
//them look normal.
private void DataGridViewFactor_CellPainting(object sender, DataGridViewCellPaintingEventArgs e){
    if (e.RowIndex > -1 && e.ColumnIndex > -1)
    {
            if (e.Value != null)
            {
                e.Handled = true;
                e.PaintBackground(e.CellBounds, true);
                StringFormat sf = new StringFormat() { LineAlignment = StringAlignment.Center };
                e.Graphics.DrawString(e.Value.ToString(), DataGridViewFactor.Font, new SolidBrush(DataGridViewFactor.ForeColor), e.CellBounds, sf);
            }
    }
}

それだけです。

お役に立てば幸いです。

于 2013-06-08T23:43:12.627 に答える