【问题标题】:WPF MVVM DataGrid Row to Another DataGridWPF MVVM DataGrid 行到另一个 DataGrid
【发布时间】:2018-05-16 16:56:50
【问题描述】:

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

View DataContext 在其后面的代码中绑定到 ViewModel,我知道它可以正常工作,因为页面上的其他控件(组合框、文本框等)可以完美运行。 dgSelectCase 中的“添加”按钮命令绑定到 ViewModel 中的 AddTo 方法,dgCaseSelected 中的“删除”按钮命令绑定到 ViewModel 中的 RemoveFrom 方法。

“添加”按钮不起作用,但更重要的是,看起来我在 dgSelectCase DataGrid 中遇到了选择绑定问题,因为当我单击一行时,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);
        }
    }

【问题讨论】:

    标签: c# wpf xaml mvvm datagrid


    【解决方案1】:

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

        <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;
    }
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-07-17
        • 2013-08-03
        • 1970-01-01
        • 2019-06-01
        • 2018-02-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多