我想要做的是在验证失败时为DataGridRow着色。我尝试使用ValueConverter,但我不知道如何从多个绑定源传递值。
我已经通过绑定到对象集合获得了datagrid。那就是a DataGridTemplateColumn中包含ComboBox和Textbox(只有一个在时间可见),而ComboBox与绑定的集合绑定源无关。
参见代码:
<DataGrid Grid.Row="4" Grid.Column="0" x:Name="DGR_Slots" Grid.ColumnSpan="5" Grid.RowSpan="3" ItemsSource="{Binding ElementName=WND_ItemCraftingWindow, Path=SelectedSchematic.Slots}" AutoGenerateColumns="False" ColumnWidth="*">
<DataGrid.Resources>
<classes:ValidationConverter x:Key="ValidationConverter" />
</DataGrid.Resources>
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Background" Value="{Binding Converter={StaticResource ValidationConverter}}" />
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Id" Binding="{Binding Id}" Visibility="Collapsed"/>
<DataGridTextColumn Header="Slot Type" Binding="{Binding SlotType}" />
<DataGridTextColumn Header="Mat Type" Binding="{Binding MaterialType}" />
<DataGridTextColumn Header="Count" Binding="{Binding MaterialCount}" />
<!--<DataGridComboBoxColumn Header="Material" />-->
<DataGridTemplateColumn Header="Material">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ComboBox Visibility="Visible" MouseDoubleClick="MaterialCell_MouseDoubleClick" ItemsSource="{Binding ElementName=WND_ItemCraftingWindow, Path=Materials}" DisplayMemberPath="Name" SelectedValuePath="Name" SelectionChanged="MaterialComboBox_SelectionChanged"/>
<TextBox Visibility="Collapsed" MouseDoubleClick="MaterialCell_MouseDoubleClick" PreviewKeyUp="MaterialCell_TextBox_PreviewKeyUp" KeyUp="MaterialCell_TextBox_KeyUp" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
WND_ItemCraftingWindow是拥有datagrid的Window,而Materials是该窗口内的ObservableCollection属性。
我需要将对象从DataGrid.ItemsSource集合(现在可以使用)和来自Combobox的SelectedItem从同一行(我不知道该怎么做)传递到ValidationConverter。
只能使用来自组合框的DataGridRow和SelectedItem中的对象来执行行的验证。
此外,我也可以使用不同的解决方案在验证后为行着色。
答案 0 :(得分:0)
好吧,我设法做到了hackish方式。
Datagrid代码(删除无意义的部分):
<DataGrid x:Name="DGR_Slots" ItemsSource="{Binding ElementName=WND_ItemCraftingWindow, Path=SelectedSchematic.Slots}" AutoGenerateColumns="False" ColumnWidth="*" IsReadOnly="True">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Material">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ComboBox Visibility="Visible" ItemsSource="{Binding ElementName=WND_ItemCraftingWindow, Path=Materials}" SelectionChanged="MaterialComboBox_SelectionChanged" />
<TextBox Visibility="Collapsed" />
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
SelectionChanged事件
private void MaterialComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// ...
var slot = (DGR_Slots.SelectedItem as SchematicSlot);
var mat = ((sender as ComboBox).SelectedItem as Material);
var row = WPFHelper.GetRow(DGR_Slots, DGR_Slots.SelectedIndex);
row.Background = new SolidColorBrush(slot.MaterialType != mat.MaterialType ? Colors.Red : Colors.White);
}
WPFHelper GetRow方法(在互联网上的某个地方找到)
static public DataGridRow GetRow(DataGrid dg, int index)
{
DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null)
{
// may be virtualized, bring into view and try again
dg.ScrollIntoView(dg.Items[index]);
row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(index);
}
return row;
}
虽然我仍然对其他解决方案持开放态度。