将 DataGrid 绑定到第二个数据网格的选定行对象,WPF Caliburn.Micro
Bind a DataGrid to the selectedrow object of a second datagrid, WPF Caliburn.Micro
我有一个绑定到 BindableCollection 的数据网格,它工作正常,我添加到 BindableCollection 的每个维修订单都显示在 Datagrid 中。
我在 "WriteOffs" 的同一视图上有第二个 Datagrid,每个 "RepairOrder" 都有一个 属性 的 BindableCollection。
我想做的是将 WriteOff DataGrid 绑定到所选行的 WriteOffs。因此,每次用户在 "RepairOrder" 数据网格中选择一行时,存储在核销 属性 中的核销就会显示在 WriteOff 数据网格中。
处理此问题的最佳方法是什么?
维修订单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;
}
显示维修订单的数据网格的 XML:
<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 用于注销的数据网格:
<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>
我正在考虑在用户选择一行时创建一个事件,但我似乎无法找到一种方法来获取将所选行放入 ViewModel 方法时的值。
我似乎找不到关于如何处理这种情况的明确教程或post。
实现最终目标最简单的方法是什么?
好的,这就是我要做的...
您需要使用 SelectedItem
,而不是 ScheduleGrid DataGrid
上的 SelectedIndex
。
所以你的 XAML
看起来像这样:
<DataGrid x:Name="ScheduleGrid" ItemsSource="{Binding RepairOrders}" SelectedItem="{Binding SelectedRepairOrder} ...."
没到ViewModel
现在您需要制作 SelectedItem
属性 或 SelectedRepairOrder
。
属性 应如下所示:
private RepairOrder _selectedRepairOrder;
public RepairOrder SelectedRepairOrder
{
get { return _selectedRepairOrder; }
set
{
if (_selectedRepairOrder == value) return;
_selectedRepairOrder = value;
NotifyOfPropertyChange(() => SelectedRepairOrder);
NotifyOfPropertyChange(() => WriteOffsCollection);
}
}
其次,因为我们有两个 DataGrids
,所以我们还需要两个 Collections
。
ScheduleGrid
应该有一个看起来像这样的 Collection
:
private BindableCollection<RepairOrder> _repiarOrdersCollection;
public BindableCollection<RepairOrder> RepairOrders
{
get { return _repiarOrdersCollection; }
set
{
_repiarOrdersCollection = value;
}
}
而 WriteOffs DataGrid
集合应该是这样的:
public BindableCollection<WriteOff> WriteOffs
{
get
{
return GetWriteOffs();
}
}
好的...现在会发生什么...正如您在 SelectedRepairOrder
属性 中看到的那样,在它更改后,它会通知您的 WriteOffs
集合它已更改.由于我们较新地设置了其 DataGrid
的值,因此我们不需要任何 setter
。
现在缺少一件事。由于您有两个集合,我相信您希望在从一个集合中选择项目后过滤其他集合中的项目?正确的?如果是,您需要扩展您的 GetWriteOffs()
方法,以获得一些国王的参数,string, int...
并在其中过滤您的数据。
我有一个绑定到 BindableCollection 的数据网格,它工作正常,我添加到 BindableCollection 的每个维修订单都显示在 Datagrid 中。
我在 "WriteOffs" 的同一视图上有第二个 Datagrid,每个 "RepairOrder" 都有一个 属性 的 BindableCollection。
我想做的是将 WriteOff DataGrid 绑定到所选行的 WriteOffs。因此,每次用户在 "RepairOrder" 数据网格中选择一行时,存储在核销 属性 中的核销就会显示在 WriteOff 数据网格中。
处理此问题的最佳方法是什么?
维修订单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;
}
显示维修订单的数据网格的 XML:
<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 用于注销的数据网格:
<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>
我正在考虑在用户选择一行时创建一个事件,但我似乎无法找到一种方法来获取将所选行放入 ViewModel 方法时的值。
我似乎找不到关于如何处理这种情况的明确教程或post。
实现最终目标最简单的方法是什么?
好的,这就是我要做的...
您需要使用 SelectedItem
,而不是 ScheduleGrid DataGrid
上的 SelectedIndex
。
所以你的 XAML
看起来像这样:
<DataGrid x:Name="ScheduleGrid" ItemsSource="{Binding RepairOrders}" SelectedItem="{Binding SelectedRepairOrder} ...."
没到ViewModel
现在您需要制作 SelectedItem
属性 或 SelectedRepairOrder
。
属性 应如下所示:
private RepairOrder _selectedRepairOrder;
public RepairOrder SelectedRepairOrder
{
get { return _selectedRepairOrder; }
set
{
if (_selectedRepairOrder == value) return;
_selectedRepairOrder = value;
NotifyOfPropertyChange(() => SelectedRepairOrder);
NotifyOfPropertyChange(() => WriteOffsCollection);
}
}
其次,因为我们有两个 DataGrids
,所以我们还需要两个 Collections
。
ScheduleGrid
应该有一个看起来像这样的 Collection
:
private BindableCollection<RepairOrder> _repiarOrdersCollection;
public BindableCollection<RepairOrder> RepairOrders
{
get { return _repiarOrdersCollection; }
set
{
_repiarOrdersCollection = value;
}
}
而 WriteOffs DataGrid
集合应该是这样的:
public BindableCollection<WriteOff> WriteOffs
{
get
{
return GetWriteOffs();
}
}
好的...现在会发生什么...正如您在 SelectedRepairOrder
属性 中看到的那样,在它更改后,它会通知您的 WriteOffs
集合它已更改.由于我们较新地设置了其 DataGrid
的值,因此我们不需要任何 setter
。
现在缺少一件事。由于您有两个集合,我相信您希望在从一个集合中选择项目后过滤其他集合中的项目?正确的?如果是,您需要扩展您的 GetWriteOffs()
方法,以获得一些国王的参数,string, int...
并在其中过滤您的数据。