【问题标题】:Pass values to ValueConverter from two different binding sources in single DataGrid将值从单个 DataGrid 中的两个不同绑定源传递给 ValueConverter
【发布时间】:2015-07-19 15:21:19
【问题描述】:

如果验证失败,我想要将 DataGridRow 涂成红色。我尝试使用 ValueConverter 来实现,但我不知道如何从多个绑定源传递值。

我有绑定到对象集合的数据网格。然后有一个 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 是拥有数据网格的 Window,Materials 是该窗口内的 ObservableCollection 属性。

我需要将 DataGrid.ItemsSource 集合中的对象(现在可以使用)和 Combobox 中的 SelectedItem 在同一行(我不知道该怎么做)传递到 ValidationConverter。

只能使用来自 DataGridRow 的对象和来自组合框的 SelectedItem 来执行行的验证。

我也愿意接受不同的解决方案,在此类验证后为行着色。

【问题讨论】:

  • 您验证数据的方法是错误的。您应该利用 WPF 中包含的验证机制。查看this 博客文章了解更多信息。
  • 好吧,我可以使用这些验证规则或 IDataErrorInfo,但我如何使用它们来获取所需的值?
  • 如果您需要从 xaml 绑定发送多个值,请使用 IMultiValueConverter

标签: wpf binding ivalueconverter


【解决方案1】:

好吧,我设法做到了。

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

虽然我仍然对其他解决方案持开放态度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-02
    • 2021-06-04
    • 2012-10-13
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多