WPF MVVM DataGrid行到另一个DataGrid

时间:2017-12-02 21:34:23

标签: c# wpf xaml mvvm datagrid

在我使用MVVM的WPF应用程序中,我有一个DataGrid(dgSelectCase)从我的ViewModel填充了一个绑定的ObservableCollection。按钮出现在第一列中,单击时,应将所选行添加到第二个DataGrid(dgCaseSelected)。

View DataContext在其后面的代码中绑定到ViewModel,我知道它的工作原理是因为页面上的其他控件(Comboboxes,Textboxes等)工作得很好。 dgSelectCase中的“添加”按钮命令绑定到ViewModel中的AddTo方法,而dgCaseSelected中的“删除”按钮命令绑定到ViewModel中的RemoveFrom方法。

“添加”按钮不起作用,但更重要的是,我看起来在dgSelectCase DataGrid中选择了Binding问题,因为当我点击一行时,我在DataGrid周围得到一个红色框。我哪里出错了?感谢任何和所有的帮助,因为我还在学习....慢慢:)。以下是代码片段。

XAML

        <DataGrid>
            <DataGrid.Columns>
            <DataGridTemplateColumn Header="Select">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Content="Add" Command="{Binding AddTo}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Header="Fac ID #" Binding="{Binding FacilityIDNum}"/>
            <DataGridTextColumn Header="OP Case #" Binding="{Binding CaseBookingNum}"/>
            <DataGridTextColumn Header="Booking Type #" Binding="{Binding BookingTypeNum}"/>
            <DataGridTextColumn Header="Booking Type" Binding="{Binding BookingType}"/>
            </DataGrid.Columns>
        </DataGrid>

        <DataGrid x:Name="dgCaseSelected"
              AutoGenerateColumns="False"
              ItemsSource="{Binding DGCaseBookingsSelected}"
              >
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Select">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button Content="Remove" Command="{Binding RemoveFrom}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn Header="Fac ID #" Binding="{Binding FacilityIDNum}"/>
                <DataGridTextColumn Header="OP Case #" Binding="{Binding CaseBookingNum}"/>
                <DataGridTextColumn Header="Booking Type #" Binding="{Binding BookingTypeNum}"/>
                <DataGridTextColumn Header="Booking Type" Binding="{Binding BookingType}"/>
            </DataGrid.Columns>
        </DataGrid>

视图模型

    private ObservableCollection<DGCaseBookings> _dgCaseBookingsList;
    private ObservableCollection<DGCaseBookings> _dgSelectedCaseBookings;
    private ObservableCollection<DGCaseBookings> _dgCaseBookingsSelected;

    public ObservableCollection<DGCaseBookings> DGCaseBookingsList
    {
        get { return _dgCaseBookingsList; }
        set
        {
            SetProperty(ref _dgCaseBookingsList, value, () => DGCaseBookingsList);
        }
    }

    public ObservableCollection<DGCaseBookings> DGSelectedCaseBookings
    {
        get { return _dgSelectedCaseBookings; }
        set
        {
            SetProperty(ref _dgSelectedCaseBookings, value, () => DGSelectedCaseBookings);
        }
    }

    public ObservableCollection<DGCaseBookings> DGCaseBookingsSelected
    {
        get { return _dgCaseBookingsSelected; }
        set
        {
            SetProperty(ref _dgCaseBookingsSelected, value, () => DGCaseBookingsSelected);
        }
    }

    public CMBookingSelectVM() : base()
    {
        DGCaseBookingsList = new ObservableCollection<DGCaseBookings>();
        DGCaseBookingsSelected = new ObservableCollection<DGCaseBookings>();
    }

    private void fillDGCaseBookingswithFacility()
    {
        using (MySqlConnection con = new MySqlConnection(dbConnectionString))
        {
            DGCaseBookingsList = new ObservableCollection<DGCaseBookings>();
            con.Open();
            string Query = ///SELECT STATEMENT WORKS FINE///
            MySqlCommand createCommand = new MySqlCommand(Query, con);
            MySqlDataReader dr = createCommand.ExecuteReader();
            int count = 1;
            while (dr.Read())
            {
                int FacilityIDNum = dr.GetInt32(0);
                int CaseBookingNum = dr.GetInt32(1);
                int BookingTypeNum = dr.GetInt32(2);
                string BookingType = dr.GetString(3);
                DGCaseBookings dgcb = new DGCaseBookings(count, FacilityIDNum, CaseBookingNum, BookingTypeNum, BookingType);
                DGCaseBookingsList.Add(dgcb);
                count++;
            }
            con.Close();
        }
    }

    public void AddTo(DGCaseBookings dgcb)
    {
        if (dgcb != null)
        {
            DGCaseBookingsSelected.Add(dgcb);
            DGCaseBookingsList.Remove(dgcb);
        }
    }

    public void RemoveFrom(DGCaseBookings dgcb)
    {
        if (dgcb != null)
        {
            DGCaseBookingsList.Add(dgcb);
            DGCaseBookingsSelected.Remove(dgcb);
        }
    }

2 个答案:

答案 0 :(得分:0)

首先,您在代码中没有提到如何将数据网格的选定项属性绑定到您的集合(事实上您实际上并没有设置第一个数据网格的itemsource,我认为你没有这样做,因为你实际上不能绑定数据网格的SelectedItems属性,因为它只是一个readonly属性。从现在开始,你只有2个选择。找到一种解决方法,将所选项目发送到您的viewmodel,或处理单行。至于第二种方法,你可以简单地这样做:

    <DataGrid ItemsSource="{Binding DGCaseBookingsList}" SelectedItem="{Binding MyItem}" SelectionMode = "Single" SelectionUnit="FullRow">
        <DataGrid.Columns>
        <DataGridTemplateColumn Header="Select">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Content="Add" Command="{Binding AddTo}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn Header="Fac ID #" Binding="{Binding FacilityIDNum}"/>
        <DataGridTextColumn Header="OP Case #" Binding="{Binding CaseBookingNum}"/>
        <DataGridTextColumn Header="Booking Type #" Binding="{Binding BookingTypeNum}"/>
        <DataGridTextColumn Header="Booking Type" Binding="{Binding BookingType}"/>
        </DataGrid.Columns>
    </DataGrid>
在您的VM中

删除DGSelectedCaseBookings并添加以下内容:

private DGCaseBookings myItem = new DGCaseBookings();
public DGCaseBookings MyItem
{
    get { return myItem; }
    set
    {
        SetProperty(ref myItem, value, () => MyItem);
    }
}

从那里,您将使用按钮的命令处理此对象。只需确保实施INotifyPropertyChanged,否则您的UI不会发现任何变化。

如果您的目标是多重选择,那么最简单的方法是处理数据网格的选择更改事件。从那里你可以做这样的事情。

private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
     MyVM vm = this.DataContext as MyVM;
     DataGrid s = sender as DataGrid;
     vm.DGSelectedCaseBookings = s.SelectedItems;
}

答案 1 :(得分:0)

在此背景下,您可以在单击按钮并添加当前行(如事件的参数)时设置事件。取当前行从datasource / ObservableCollection中选择它并将其添加到另一个数据集中,例如_dgSelectedCaseBookings。

之后,您可以在UI上刷新新的_dgSelectedCaseBookings。