DataRelation Filterfunktion

20/06/2008 - 14:38 von Robert Oberholzer | Report spam
Hallo NG

Habe eine Datarelation erstellt und möchte nun in der Master-Table filtern.
Habe schone mehrere Möglichkeiten mit BindingSource, DataView etc.
ausprobiert.
Aber irgenwie kriege ich dies nicht hin.

DataColumn[] colParentFund = new DataColumn[1];
colParentFund[0] = dsReportData.Tables["Fund"].Columns["strKey"];
DataColumn[] colChildRc = new DataColumn[1];
colChildRc[0] = dsReportData.Tables["RC"].Columns["RCKEY"];

DataRelation drFundRc = new DataRelation("FundToRc", colParentFund,
colChildRc, false);
dsReportData.Relations.Add(drFundRc);

dgvSelection.DataSource = dsReportData;
dgvSelection.DataMember = "Fund";

dgvSelectionDetail.DataSource = dsReportData;
dgvSelectionDetail.DataMember = "Fund.FundToRc";

Wie und wo füge ich nun einen Filter für die Masterdatensàtze ein.

Danke
Robert Oberholzer
 

Lesen sie die antworten

#1 Elmar Boye
20/06/2008 - 18:51 | Warnen spam
Hallo Robert,

Robert Oberholzer schrieb:
Habe eine Datarelation erstellt und möchte nun in der Master-Table filtern.
Habe schone mehrere Möglichkeiten mit BindingSource, DataView etc.
ausprobiert.
Aber irgenwie kriege ich dies nicht hin.



Um das "hinzukriegen" muß Du zunàchst den zugrundeligenden
Mechanismus verstehen.

Die Bindung bei komplexen Steuerelementen wie dem DataGridView
erfolgt letztendlich über einen CurrencyManager.
Die BindingSource (ab .NET 2.0) wiederum stellt den auch für die
Designzeit als Komponente zur Verfügung - vorher war er nur im
Code über den BindingContext ansprechbar :
<URL:http://msdn.microsoft.com/de-de/lib...t.aspx>
(und das geht weiterhin, weil eben nur Verpackung).

Im Falle eines DataSet erfolgt die Bindung immer an eine DataView.
Gibt man eine DataTable direkt an, so wird dazu deren DefaultView bemüht.
Änderungen an den Eigenschaften dort wirken sich ebenfalls auf die
aktuelle Bindung aus - sollte man IMO aber eher vermeiden, weil das
im Zusammenhang schnell undurchsichtig wird.

Das Binden an eine DataRelation erfolgt wiederum über das DataSet,
da dort die DataRelation Auflistung angesiedelt ist. Und der Pfad
(Binding.BindingPath) hat dabei Aufbau [Master/PrimàrTabelle].[Relationsname]
(und weitere Relationen sind möglich).

Um nun die Master-Tabelle (bei Dir "Fund") zu filtern, muß Du den
RowFilter der zugrundeliegende DataView (die an bewußtem CurrencyManager
hàngt) auf einen Ausdruck etzen - was da möglich ist steht im wesentlichen
in der Dokumentation zu DataColumn.Expression:
<URL:http://msdn.microsoft.com/en-us/lib...n.aspx>

dgvSelection.DataSource = dsReportData;
dgvSelection.DataMember = "Fund";

dgvSelectionDetail.DataSource = dsReportData;
dgvSelectionDetail.DataMember = "Fund.FundToRc";

Wie und wo füge ich nun einen Filter für die Masterdatensàtze ein.



Da Du hier direkt gebunden hast ist, der universellste (und auch
kryptischste ;-) Zugriff über den BindingContext:
(DataView)((CurrencyManager)this.BindingContext[dataSet, "Fund"]).List)
.RowFilter = "[Spalte1] = 'ABC' OR [Spalte2] = 4711";

Einfacher und durchsichtiger wird es wenn Du einen BindingContext
verwendest, da dort die RowFilter Eigenschaft direkt zugànglich ist.

Ich habe unten mal für die allseits beliebte Northwind.Customers->Orders
drei Varianten zum Nachvollziehen angehàngt. Einmal wie oben, einmal
über eine explizit erstellte DataView und die (in der Regel vorzuziehende)
Variante über zwei BindingSource.

Das Formular enthàlt zwei DataGridViews und zwei BindingSource Instanzen.

Gruß Elmar

private void Form_Load(object sender, EventArgs e)
{
DataSet dataSet = CustomerOrdersDataSet();

// Die drei Varianten...
DataGridBindingSource(dataSet);

//DataGridBindDataView(dataSet);

//DataGridBindDataSet(dataSet);

this.customersDataGridView.AutoGenerateColumns = true;
this.ordersDataGridView.AutoGenerateColumns = true;
}

private void DataGridBindingSource(DataSet dataSet)
{
// Via BindingSource
this.customersBindingSource.DataSource = dataSet;
this.customersBindingSource.DataMember = "Customers";

this.ordersBindingSource.DataSource = customersBindingSource;
this.ordersBindingSource.DataMember = "Customer2Orders";

this.customersDataGridView.DataSource = this.customersBindingSource;
this.ordersDataGridView.DataSource = this.ordersBindingSource;

// Ein Filter (auf die DataView) der BindingSource
this.customersBindingSource.Filter = "[Country] = 'Germany'";
}

private void DataGridBindDataView(DataSet dataSet)
{
// Über eine DataView
DataView customersView = new DataView(dataSet.Tables["Customers"]);
this.customersDataGridView.DataSource = customersView;
this.customersDataGridView.DataMember = "";

this.ordersDataGridView.DataSource = customersView;
this.ordersDataGridView.DataMember = "Customer2Orders";

// Ein Filter auf die DataView
customersView.RowFilter = "[Country] = 'Germany'";
}

private void DataGridBindDataSet(DataSet dataSet)
{
// Direkt
// Ist DataSet.Tables["Customers"].DefaultView
this.customersDataGridView.DataSource = dataSet;
this.customersDataGridView.DataMember = "Customers";

// Relation DataView
this.ordersDataGridView.DataSource = dataSet;
this.ordersDataGridView.DataMember = "Customers.Customer2Orders";

// Ein Filter auf die DataView via BindingContext
// ist ein RelatedCurrencyManager
((DataView)((CurrencyManager)this.BindingContext[dataSet, "Customers"]).List)
.RowFilter = "[Country] = 'Germany'";
}

private DataSet CustomerOrdersDataSet()
{
// Füllen eines DataSets mit Customers und Orders
DataSet dataSet = new DataSet("CustomerOrders");
// Verbindung zur Northwind anpassen
using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.NorthwindConnectionString))
{
connection.Open();
using (SqlDataAdapter adapter = new SqlDataAdapter(
"SELECT * FROM dbo.Customers;"
+ "SELECT * FROM dbo.Orders;",
connection))
{
adapter.MissingMappingAction = MissingMappingAction.Passthrough;
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;

adapter.TableMappings.Add("Table", "Customers");
adapter.TableMappings.Add("Table1", "Orders");
adapter.Fill(dataSet);

// Relation zwischen Customers und Orders erstellen
dataSet.Relations.Add("Customer2Orders",
dataSet.Tables["Customers"].Columns["CustomerID"],
dataSet.Tables["Orders"].Columns["CustomerID"],
true);
}
connection.Close();
}
return dataSet;
}

Ähnliche fragen