简体   繁体   中英

Bind a DataGrid to the selectedrow object of a second datagrid, WPF Caliburn.Micro

I have a datagrid that is bound to a BindableCollection, this is working properly, every repair order I add to the BindableCollection shows in the Datagrid.

I have a second Datagrid on the same view for "WriteOffs", Each "RepairOrder" has a property of BindableCollection.

What I am trying to do is bind the WriteOff DataGrid to the WriteOffs of the selected row. So every time the user selects a row in the "RepairOrder" datagrid the write offs stored in the writeoff property is shown in the WriteOff datagrid.

What is the best way to handle this?

RepairOrder class:

public string ControlNumber { get; set; }
        public double Value { get; set; }
        public string Note { get; set; }
        public string Schedule { get; set; }
        public int Age { get; set; }
        public List<WriteOff> WriteOffs { get; set; }



        public RepairOrder(string CN, string SC, double VL)
        {
            ControlNumber = CN;
            Schedule = SC;
            Value = Math.Round(VL,2);
            Note = null;
            WriteOffs = new List<WriteOff>();
        }

        public RepairOrder()
        {

        }

        public void AddWriteOff(WriteOff WO)
        {
            WriteOffs.Add(WO);
        }

        public BindableCollection<WriteOff> GetWriteOffs()
        {
            BindableCollection<WriteOff> temp = new BindableCollection<WriteOff>();
            foreach (var item in WriteOffs)
            {
                temp.Add(item);
            }
            return temp;
        }

        public static RepairOrder FromCSV(string CSVLine, string Sched)
        {
            string[] values = CSVLine.Split(',');
            RepairOrder rep = new RepairOrder();
            rep.ControlNumber = values[2];
            rep.Value = Math.Round(double.Parse(values[5]),2);
            rep.Age = int.Parse(values[4]);
            rep.Schedule = Sched;
            return rep;
        }

The XML for the Data grid showing the repair orders:

<Border BorderBrush="Black" BorderThickness="2" CornerRadius="5" Grid.Column="1" Grid.Row="1">
                <DataGrid  x:Name="ScheduleGrid" ItemsSource="{Binding RepairOrders}" CanUserSortColumns="True" AutoGenerateColumns="False" SelectedIndex="{Binding SelectedRepairOrder}" SelectionMode="Single">

                    <DataGrid.Columns>
                        <DataGridTextColumn Header="Schedule" Binding="{Binding Schedule}" Width="75" IsReadOnly="True"/>
                        <DataGridTextColumn Header="Control Number" Binding="{Binding ControlNumber}" Width="110" IsReadOnly="True"/>
                        <DataGridTextColumn Header="Age" Binding="{Binding Age}" Width="50" IsReadOnly="True"/>
                        <DataGridTextColumn Header="Value" Binding="{Binding Value, StringFormat=C}" Width="75" IsReadOnly="True"/>
                        <DataGridTextColumn Header="Note" Binding="{Binding Note}" Width="*"/>
                    </DataGrid.Columns>
                </DataGrid>
            </Border>

XML for the Data grid for the write-offs:

<Border Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" BorderBrush="Black" BorderThickness="2" CornerRadius="5" Margin="5,2,5,5">
                    <StackPanel Orientation="Vertical">
                        <TextBlock Text="Write Off List" HorizontalAlignment="Center" FontSize="20"/>
                        <DataGrid ItemsSource="{Binding WriteOffs}" AutoGenerateColumns="False">
                            <DataGrid.Columns>
                                <DataGridTextColumn Header="Account" Binding="{Binding Account}" Width="100" IsReadOnly="True"/>
                                <DataGridTextColumn Header="Description" Binding="{Binding Description}" Width="200" IsReadOnly="True"/>
                                <DataGridTextColumn Header="Amount" Binding="{Binding WriteOffAmount}" Width="*" IsReadOnly="True"/>
                            </DataGrid.Columns>
                        </DataGrid>
                    </StackPanel>
                </Border>

I was thinking of making an event when the user selects a row, but I can't seem to find a way to get the value if the selected row into the ViewModel method.

I can't seem to find a clear tutorial or post on exactly how to hand this situation.

What is the easiest way to accomplish my final goals?

Okay this is the way I would do...

Instead of SelectedIndex on your ScheduleGrid DataGrid you need to use SelectedItem . So your XAML would look like this:

 <DataGrid  x:Name="ScheduleGrid" ItemsSource="{Binding RepairOrders}" SelectedItem="{Binding SelectedRepairOrder} ...."

Not to the ViewModel Now you need to make the SelectedItem property, or SelectedRepairOrder . The property should look like this:

 private RepairOrder _selectedRepairOrder;
 public RepairOrder SelectedRepairOrder
        {
            get { return _selectedRepairOrder; }
            set
            {
                if (_selectedRepairOrder == value) return;
                _selectedRepairOrder = value;
                NotifyOfPropertyChange(() => SelectedRepairOrder);
                NotifyOfPropertyChange(() => WriteOffsCollection);
            }
        }

Second, since we have two DataGrids we need also two Collections . The ScheduleGrid should have a Collection who looks like this:

   private BindableCollection<RepairOrder> _repiarOrdersCollection;
        public BindableCollection<RepairOrder> RepairOrders
        {
            get { return _repiarOrdersCollection; }
            set
            {
                _repiarOrdersCollection = value;
            }
        }

And the WriteOffs DataGrid collection should be like this:

        public BindableCollection<WriteOff> WriteOffs
        {
            get
            {
                return GetWriteOffs();
            }
        }

Okay... now what happens... As you can see in your SelectedRepairOrder property, after it changes, it will notify your WriteOffs collection that it has changed. And since we are newer setting the value of its DataGrid , we don't need any setter . Now one thing is missing. Since you have two collections, I believe that you want after selecting item from one collection to filter the items on other collection? Right? If yes, the you need to extend your GetWriteOffs() method, to have parameters of some king, string, int... and inside it filter your data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM