2017-03-10 15 views
0

這是我在這個論壇上的第一篇文章,雖然我是一個長期潛伏者。我已經開始學習WPF大約幾個月了,我正在嘗試創建一個僅用於培訓目的的應用程序。WPF:Databinding到DataGrid

我有一個後端數據庫,我使用EF6 ORM添加到我的應用程序中。在我的應用程序中,我有一個ComboBox,它需要由數據庫表中的列填充。我可以使用綁定到列表來完成。

我遇到問題的部分是DataGrid。需要根據在ComboBox中選擇的Item填充DataGrid的列。

我的數據庫:

Here is my database structure

正如你所看到的,在學校有好幾個部門,每個部門的那些都有一個HOD和學生的實力。

我的應用程序:

Here is the snapshot of the app

ComboBox將與學校的名稱進行填充。一旦選擇了學校名稱,DataGrid將被填充。 DataGrid將爲學校的每個部門提供每行。所以我需要將相應的欄目與相應學校的部門聯繫起來。我得到了很多。不過,我想在反饋TextBox中保存用戶輸入的評論。

我不明白如何創建一個類,以便我可以將DataGrid綁定到它的對象。是否可以將DataGrid綁定到一個對象,然後將這些列單獨綁定到另一個對象?

編輯

從數據庫中創建的實體

除此之外,我有兩個類:

這應該被綁定到數據網格。並且FeedbackLine是:

public class FeedbackLine: INotifyPropertyChanged 
{ 
    private string _dept; 

    public string Department 
    { 
     get { return _dept; } 
     set { _dept = value; 
      OnPropertyChanged("Department"); 
     } 
    } 

    private string _HOD; 

    public string HOD 
    { 
     get { return _HOD; } 
     set { _HOD = value; 
      OnPropertyChanged("HOD"); 
     } 
    } 

    private int _strength; 

    public int Strength 
    { 
     get { return _strength; } 
     set { _strength = value; 
      OnPropertyChanged("Strength"); 
     } 
    } 

    private bool _isSelected; 

    public bool Selected 
    { 
     get { return _isSelected; } 
     set { _isSelected = value; 
      OnPropertyChanged("Selected"); 
     } 
    } 

    private string _comment; 

    public string Comment 
    { 
     get { return _comment; } 
     set { _comment = value; 
      OnPropertyChanged("Comment"); 
     } 
    } 

    private void OnPropertyChanged(string v) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(v)); 
    } 



    public event PropertyChangedEventHandler PropertyChanged; 
} 

我對ViewModel沒有太多進展。問題是,我對LINQ不太好。而且有太多的類和對象,我不知道哪一個與哪個綁定。我能得到的唯一含糊的想法是我必須使用LINQ來使用所選的School來查詢數據庫,然後使用它來填充FeedbackLines

編輯2: 的人誰的興趣,這裏是我的模型圖中的WPF: Model Diagram

編輯3: 我想我感到困惑的視圖模型。屏幕上顯示的數據不一定是要保存的數據。例如,我不想保存未選中的行。我的Feedback類嘗試顯示數據並保存。問題在於此。不能DataGrid綁定到一個對象,而其列被綁定到其他對象?例如,如果我選擇爲部門使用Combobox。然後我需要使用ItemsSource來顯示項目,但只需要保存SelectedItem。我找不到解決這兩個問題的方法。

+2

是否可以共享代碼? –

+0

發佈您的代碼。 –

+0

通過代碼,你的意思是viewmodel還是xaml? –

回答

0

我會改變你的反饋構造

public Feedback(string school, List<FeedbackLine> feedbackLines) 
{ 
    School = school; 
    FeedbackLines = new ObservableColleytion<FeedbackLine>(feedbackLines); 
} 

這是一個更好的架構,如果你的數據視圖模型不具有對數據庫的連接。你可以把你的選擇放在一個單獨的課堂上。

如果您需要LINQ聲明幫助,我可以幫助您。

在您的反饋構造你寫

//but then what? 

當你有你的數據,你可以創建FeedbackLines的情況下,增加他們在新構造我上面顯示。

當你不喜歡你在其他的ViewModels做到了這您的視圖模型(這是你的DataContext視圖)需要一個

public void ObservableCollection<Feedback> Feedbacks 

與INotifyPropertyChanged的。

在你的xaml中你有你的ComboBox和學校。爲該組合框命名,例如SchoolsComboBox。 在你的DataGrid 您創建了一個匿名類型在此線

Source={Binding ElementName=SchoolsComboBox, Path=SelectedItem.FeedbackLines} 

/編輯添加LINQ。只需創建一個FeedbackLine,而你沒事。

var feedbackLines = Context.Schools.Where(c => c.SchoolName == school) 
            .Select(c => new FeedbackLine 
              { 
               Department = c.AvailableDepts.Dept, 
               HOD = c.AvailableDepts.HeadOfDept, 
               Strength = c.AvailableDepts.StudentStrength} 
            .ToList() 
+0

感謝您的澄清。它使建築更清潔。至於LINQ,我仍然陷入困境。我正在使用類似'var FeedbackLines = Context.Schools.Where(c => c.SchoolName == school).Select(c => new {Department = c.AvailableDepts.Dept,HOD = c.AvailableDepts.HeadOfDept, Strength = c.AvailableDepts.StudentStrength} .ToList()'但是這會返回一個IEnumerable的匿名對象。我應該如何將它轉換爲FeedbackLines? –

+0

我已經編輯了我的答案並添加了LINQ語句,如果它工作,我會很高興當你upvote並接受我的答案:) –

+0

已經upvote,但我的聲譽不允許它公開。抱歉。感謝LINQ。它起作用了,至少粗略的檢查表明了這一點。 –

0

你可以做出這樣的事情。我相信它可以寫得更好,但它的工作原理。

在您的視圖模型做出3個屬性是實現INotifyPropertyChanged

一個用於您的收藏將你綁定到組合框從組合框(使它的ObservableCollection),一個用於的SelectedItem(你把它綁定到組合框的SelectedItem)和另外的ObservableCollection,你會綁定到數據網格)

例如你在XAML:

<Grid> 
     <ComboBox ItemsSource="{Binding Products}" 
        SelectedItem="{Binding SelectedProduct}" 
        HorizontalAlignment="Left" 
        VerticalAlignment="Top" 
        Width="200" 
       Margin="20" 
       IsSynchronizedWithCurrentItem="True" /> 

    <DataGrid ItemsSource="{Binding SelectedOne}" 
       HorizontalAlignment="Right " 
       VerticalAlignment="Center" 
       Width="300" 
       IsSynchronizedWithCurrentItem="True"> 
    </DataGrid> 

並且在你的ViewModel中你可以有這樣的東西。

 public ObservableCollection<Product> Products 
      { 
       get { return _products; } 
       set 
       { 
        if (value != _products) 
        { 
         _products = value; 
         OnPropertyChanged(); 
        } 
       } 
      } 

      private ObservableCollection<Product> _selectedOne; 
      public ObservableCollection<Product> SelectedOne 
      { 
       get { return _selectedOne; } 
       set { 
         _selectedOne = value; 
         OnPropertyChanged(); 
        } 
      } 

      public int SelectedProductId 
      { 
       get { return _selectedProductId; } 
       set 
       { 
        if (value != _selectedProductId) 
        { 
         _selectedProductId = value; 
         OnPropertyChanged(); 
        } 
       } 
      } 

      public Product SelectedProduct 
      { 
       get { return _selectedProduct; } 
       set 
       { 
        if (value ! = _selectedProduct) 

       { 
        _selectedProduct = value; 

        // clear your list of selected objects and then add just selected one 
        // or you dont clear it, and items will be added in DataGrid when selected in ComboBox 
        SelectedOne.Clear(); 
        SelectedOne.Add(_selectedProduct); 

        OnPropertyChanged(); 
       } 
      } 
     } 


     #region INotifyPropertyChanged Members 

     public event PropertyChangedEventHandler PropertyChanged = delegate { }; 

     protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "") 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 

     #endregion 

要填充產品的代碼,DataGrid將通過從ComboBox中選擇Item來填充。

你可以在ViewModel的構造函數中做這樣的事情。

public MainWindowViewModel() 
     { 
      if (!DesignerProperties.GetIsInDesignMode(new DependencyObject())) 
      { 
       using (YourDbContext context = new YourDbContext()) 
       { 
        var productList = new ObservableCollection<Product>(context.Products); 
        productList.ToList() 
        Products = productsList; 
       } 
      } 
     } 
+0

填充數據網格或組合框的代碼在哪裏? –

+0

我已經在ViewModel中添加了樣本,您可以如何填充您的列表中的od項目。 DataGrid將通過從ComboBox中選擇Item來填充,這就是爲什麼我們將SelectedOne屬性設置爲Collection,並且如果您想在DataGrid中添加更多(如堆棧),或者您可以通過先前清除該集合來添加一個樣本在SelectedProduct Set屬性中創建。 –