簡體   English   中英

WPF:數據綁定到DataGrid

[英]WPF: Databinding to a DataGrid

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

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

我遇到麻煩的部分是DataGrid 需要根據ComboBox選擇的Item填充DataGrid的列。

我的數據庫:

這是我的數據庫結構

如您所見,學校有幾個系,每個系都有一個HOD和一個學生實力。

我的應用程序:

這是應用程序的快照

ComboBox將填充學校名稱。 選擇學校名稱后,將填充DataGrid DataGrid將為學校的每個部門提供每一行。 因此,我需要將相應的列與相應學校的部門綁定。 我得到了。 但是,然后我想將用戶輸入的注釋保存在Feedback TextBox

我不明白如何創建一個類,以便可以將DataGrid綁定到它的對象。 是否可以將DataGrid綁定到對象,然后將列分別綁定到另一個對象?

編輯

除了從數據庫創建的實體之外,我還有兩個類:

class Feedback : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string _school;

    public string School
    {
        get
        {
            return _school;
        }

        set
        {
            _school = value;
            OnPropertyChanged("School");
        }
    }

    private ObservableCollection<FeedbackLine> _feedbackLines;

    public ObservableCollection<FeedbackLine> FeedbackLines
    {
        get
        {
            return _feedbackLines;
        }

        set
        {
            _feedbackLines = value;
            OnPropertyChanged("FeedbackLines");
        }
    }

    public Feedback(string school)
    {
       //Insert some Linq Query to populate the FeedbackLines
       //something like
       //var FeedbackLines = Context.Schools.Where(c => c.SchoolName == school)
       //                                   .Select(c => new {Department = c.AvailableDepts.Dept, etc etc}.ToList();
       //but then what?
    }

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

這應該綁定到數據網格。 而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中的模型圖模型圖

編輯3:我認為我對ViewModel感到困惑。 屏幕上顯示的數據不一定是要保存的數據。 例如,我不想保存未選擇的行。 我的Feedback類嘗試顯示並保存數據。 問題就在這里。 不能將DataGrid綁定到對象,而將其列綁定到其他對象? 例如,如果我選擇對部門使用組合Combobox 然后,我需要使用ItemsSource來顯示項目,但只需要保存SelectedItem 我找不到將這兩個問題分開的方法。

我會更改您的Feedback構造函數

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

如果您的數據視圖模型沒有與數據庫的連接,則它是一種更好的體系結構。 您可以將選擇放在單獨的類中。

如果您需要有關LINQ語句的幫助,我可以為您提供幫助。

在您的Feedback構造函數中,您編寫了

//but then what?

收到數據后,您可以創建FeedbackLines實例,以將它們添加到上面顯示的新構造函數中。

完成此操作后,您的viewmodel(即視圖的DataContext)需要一個

public void ObservableCollection<Feedback> Feedbacks

使用INotifyPropertyChanged就像在其他視圖模型中一樣。

在您的xaml中,您可以在學校中找到ComboBox。 給該組合框起一個名字,例如SchoolsComboBox。 在您的DataGrid中編寫以下行

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

/ edit用於添加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()

你可以做這樣的事情。 我敢肯定它可以寫得更好,但它可以工作。

在您的ViewModel中,制作3個實現INotifyPropertyChanged的屬性

一個用於您的集合,它將綁定到您的ComboBox(將其設置為ObservableCollection),一個用於您的ComboBox的SelectedItem(將其綁定到comboBox中的SelectedItem),另一個用於將ObservableCollection綁定到DataGrid)

例如,您在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

通過代碼填充產品,可以通過從ComboBox中選擇Item來填充DataGrid。

您可以進入ViewModel構造函數並進行類似的操作。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM