2012-10-12 130 views
0

在我的應用程序中,我有一張表,其中包含組織內各個區域的數據,其中包含關於每個區域的統計數據的相關表格。爲簡單起見,我會將它們表示爲:將文本框綁定到BindingSource IList屬性中的特定DataRowView

____________   ________________   ________________ 
|Region |   |RegionHasDemo |   |DemoCategories| 
|   |1  *|    |*  1|    | 
|-RegionID |----------|-RegionID  |----------|-CatID  | 
|-City  |   |-CatID  |   |-SortOrder | 
|-Zip  |   |-Population |   |-Archive  | 
|-State |   |______________|   |______________| 
|__________|   

DemoCategories表包含人口統計類型。例如,讓我們說RegionHasDemo代表我的地區的年齡人口。 DemoCategories中的CatID將是Age20to30,Age20to40等等的值,以便RegionHasDemo代表所有地區的年齡組人口。

在我的應用程序中,我想創建一個表單來添加區域數據以及所有相關數據。爲此,我創建了兩個綁定源,一個用於RegionData,另一個用於RegionHasDemo,它包含RegionData,因爲它是DataSource。出於各種原因,我希望通過將單個文本框綁定到RegionHasDemoBindingSource的List屬性中包含的DataRowViews來輸入RegionHasDemo的數據。請注意,我不想使用網格視圖。

這裏是我用來每次綁定到文本框的RegionData改變當前屬性的代碼:

注:表名是從我的樣本,RegionData =單位不同; RegionHasDemo = UnitExp; DemoCategories = CatExp。

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Data.OleDb; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Diagnostics; namespace DBsample { public partial class Form1 : Form { private DataTable DataSource; private string relatedTableName; /// <summary> /// Holsd the values needed to define my text box rows and /// relate them to the table containing their human readable /// names, sort order, and active record status. /// </summary> private struct textBoxRow { public string Key { get; set; } public TextBox TBox { get; set; } public Label NameLabel { get; set; } public string Name { get; set; } public int Value { get; set; } } textBoxRow[] rows; public Form1() { InitializeComponent(); DataSource = injuryDB.UnitExp; relatedTableName = "CatExpUnitExp"; } private void Form1_Load(object sender, EventArgs e) { this.uNITSTableAdapter.Fill(this.injuryDB.UNITS); this.catExpTableAdapter1.Fill(this.injuryDB.CatExp); this.unitExpTableAdapter1.Fill(this.injuryDB.UnitExp); // Fill data table // Associate them in the struct in sorted order // Get a list of categories DataTable catTable = DataSource.ParentRelations[relatedTableName].ParentTable; // Sort them while leaving out the ones we don't want List<DataRow> tbr = (from r in catTable.AsEnumerable() where r.Field<bool>("ActiveRecord") orderby r.Field<int>("SortOrder") select r).ToList(); // The rows we are going to show rows = new textBoxRow[tbr.Count]; tableLayoutPanel1.RowStyles.Clear(); int rowIndex = 0; // Create rows and add them to the form foreach (DataRow r in tbr) { textBoxRow tRow = new textBoxRow(); Label lbl = new Label(); lbl.Text = r.Field<string>("CatName"); TextBox tb = new TextBox(); tRow.Key = r.Field<string>("Category"); tRow.Name = r.Field<string>("CatName"); tRow.TBox = tb; tRow.NameLabel = lbl; tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize)); tableLayoutPanel1.Controls.Add(tRow.NameLabel, 0, rowIndex); tableLayoutPanel1.Controls.Add(tRow.TBox, 1, rowIndex); rows[rowIndex] = tRow; rowIndex++; } // Refresh the bindings in the text boxes when the current item changes unitCatExpBindingSource.CurrentItemChanged += currentItemChanged; currentItemChanged(null, null); } private void uNITSBindingNavigatorSaveItem_Click(object sender, EventArgs e) { bool validated = this.Validate(); if(validated == true) Debug.WriteLine("Validated data to be saved"); else Debug.WriteLine("Did not validate data to be saved"); this.uNITSBindingSource.EndEdit(); int recordsUpdated = this.tableAdapterManager.UpdateAll(this.injuryDB); Debug.WriteLine(string.Format("{0} records were changed", recordsUpdated)); } private void currentItemChanged(object sender, EventArgs e) { if (rows == null) return; // For some reason I have to pass this into the bindingSource's find method instead of a // straight string of the column name. It has something to do with the fact that we are // binding to a data relation instead of a DataTable i think. Wadded through so many forums for this... PropertyDescriptor pdc = unitCatExpBindingSource.CurrencyManager.GetItemProperties()["Cat"]; // Rebind each text box row foreach (textBoxRow tBoxRow in rows) { tBoxRow.TBox.DataBindings.Clear(); // If the record doesn't exist then that means the population for that group is zero tBoxRow.TBox.Text = "0"; //tbr.TBox.Leave -= existingRecordTBoxChanged; //tbr.TBox.Leave -= nonExistingRecordTBoxChanged; // Get the index of the source I want to bind to using the text int bindingIndex = unitCatExpBindingSource.Find(pdc, tBoxRow.Key); //object bs = unitCatExpBindingSource[bindingIndex]; if (bindingIndex >= 0) { Binding b = tBoxRow.TBox.DataBindings.Add("Text", unitCatExpBindingSource[bindingIndex], "Jumps", true); } else { // TODO: Create an event that adds a new to the demo table if number not 0 } } } // TODO: for this to work the delete options of the relationships // for Units -> category tables need to be set to cascade private void existingRecordTBoxChanged(object sender, EventArgs e) { TextBox tBox = (TextBox)sender; if (tBox.Text == "" || tBox.Text == "0") { //DataRow d = (DataRow)tBox.DataBindings[0].DataSource; } } private void nonExistingRecordTBoxChanged(object sender, EventArgs e) { TextBox tBox = (TextBox)sender; if (!(tBox.Text == "" || tBox.Text == "0")) { // TODO: Add record to the database } } } <code>

我的問題是,雖然當我的結合似乎是工作好觀看,即文本框,當我通過單位導航改變。這些更改不保存到數據庫。我在文本框中所做的更改將保留在DataSet中(當我離開記錄並返回它們時保持不變),但是當我保存dataSet關閉表單並將其重新打開時,所做的更改就消失了。就好像dataSet沒有被通知那些值被改變了。此外,如果我將相關數據放在數據網格的一側,則可以修改DataGridView中的數據,並且可以保存數據。另外,當我更改我的文本框中的數據時,新值將顯示在DataGridView中,但仍然不會保存...

我想知道是我用來將文本框綁定到數據正確。這意味着,我可以以包含在綁定源中的DataRowView的形式綁定數據,並期望它的行爲與我直接使用綁定源相同?

非常感謝您的幫助。我希望我已經提供了足夠的信息讓你繼續。請記住,此代碼示例來自原型。我明白這不是最佳做法。這表示我會很感激任何建設性的批評。

+0

更新:經過一些進一步的測試,並在代碼中放入一些換行符後,我發現雖然大多數文本框都不起作用,但其中一個文本框卻起作用。在比較文本框中的屬性後,我發現沒有工作的文本框的屬性IsEdit和delayBeginEdit設置爲false。是我綁定文本框的方式,所以我只能綁定一個控件到BindingSource? –

回答

1

多的試驗和錯誤之後,我發現這個問題。問題是我將我的文本框綁定到DataRowView對象。我不確定,但我認爲DataRowView只能在GridView或ListView組件中專用。在我的項目中,我想單獨將每個DataRowView綁定到單獨的文本框,這會導致問題,因爲DataRowViews似乎共享某種綁定屬性,使得只有其中一個文本框被正確綁定。解決方法是從DataRowView中取出DataRow對象並將文本框綁定到該對象。如果任何人有任何關於數據綁定上下文中DataRow和DataRowViews之間差異的任何意見,那將非常感激。

0

我在Combobox中有相同的probs我已經解決了它。我的代碼看起來像

<sdk:DataGridTemplateColumn Width="150" Header="EstimateIOName"> 
       <sdk:DataGridTemplateColumn.CellEditingTemplate> 
        <DataTemplate> 
         <ComboBox x:Name="cbo" ItemsSource="{StaticResource IOList}" SelectedValue="{Binding Path=EstimateIOName,Mode=TwoWay}" SelectedValuePath="EstimateIOName" SelectionChanged="cbo_SelectionChanged" DropDownClosed="cbo_DropDownClosed" ></ComboBox> 
        </DataTemplate> 
       </sdk:DataGridTemplateColumn.CellEditingTemplate> 
      </sdk:DataGridTemplateColumn> 


      <sdk:DataGridTemplateColumn Width="180" Header="Selected EstimatedIOName" IsReadOnly="True"> 
       <sdk ataGridTemplateColumn.CellEditingTemplate> 
        <DataTemplate> 
         <TextBlock x:Name="cbo1" Text="{Binding Path=EstimateIOName,Mode=TwoWay}"></TextBlock> 
        </DataTemplate> 
       </sdk:DataGridTemplateColumn> 

我的代碼背後看像

LoadOperation<ATDueDate> Load1 = context1.Load<ATDueDate>(context1.GetATDueDatesByEntityQuery("I")); 
     Load1.Completed += (s, ea) => 
     { 
      this.DataContext = Load1.Entities; 
      comboBox2.ItemsSource = Load1.Entities.Select(a => a.PackageName.Substring(1,2)).Distinct(); 
     }; 

按鈕單擊

private void button1_Click(object sender, RoutedEventArgs e) 
    { 

     context1.SubmitChanges(); 

     MessageBox.Show("Changes Saved"); 
    } 
+0

嗯。我不確定這是如何工作的。我不熟悉Silverlight或WPF,所以我不知道你在做什麼。我認爲Forms控件中的數據綁定看起來與Silverlight中的數據綁定有很大不同。 –

相關問題