【问题标题】:Bind multiple cells value from datagrid column to a single textbox将 datagrid 列中的多个单元格值绑定到单个文本框
【发布时间】:2016-12-22 09:12:11
【问题描述】:

在我的 wpf 项目中,我有一个由数据集填充的数据网格,其中包含一些列和许多行。我想遍历 Column[1] Rows[i] (例如获取数据网格中所有行的 column[1] 单元格内的值)。 我的问题是如何将这些单元格值绑定到单个文本框?我知道使用多重绑定是实现解决方案的方法之一,但我没有找到任何帮助关于通过数据网格对文本框进行多重绑定。例如,我已经阅读了以下问题:

How to bind multiple values to a single WPF TextBlock?

How to use a MultiBinding on DataGridTextColumn?

此外,绑定单个值是可以实现的,我已经做到了。 我将不胜感激任何帮助。提前致谢!!

我的 XAML:

<DataGrid x:Name="datagridbatch"
          FontSize="13.333" FontWeight="Normal"
          IsReadOnly="True"
          SelectionChanged="datagridbatch_SelectionChanged"  
          SelectionUnit="FullRow" SelectionMode="Single"
          VerticalAlignment="Top" HorizontalAlignment="Right"
          Height="615" Width="373" Margin="0,0,0,-582"
          CanUserResizeColumns="False" CanUserResizeRows="False"
          CanUserDeleteRows="False" CanUserAddRows="False"
          RowHeight="30"
          Grid.Row="5" Grid.Column="1"
          CanUserReorderColumns="False" CanUserSortColumns="False"
          ColumnHeaderHeight="25" ColumnWidth="*"
          ScrollViewer.CanContentScroll="True"
          ScrollViewer.VerticalScrollBarVisibility="Auto" />
<TextBox x:Name="input2"
         Margin="0,0,0,0" Width="490" Height="30"
         Grid.Row="0" Grid.Column="1"
         HorizontalAlignment="Left"
         Background="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}"
         FontSize="13.333" FontWeight="Normal"
         Text="{Binding SelectedItem.UNIQUEPART_ID, ElementName=datagridbatch}"
         BorderBrush="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}"
         FontFamily="Tahoma"
         IsReadOnlyCaretVisible="True"
         HorizontalScrollBarVisibility="Auto"
         ScrollViewer.CanContentScroll="True"/>

【问题讨论】:

  • 您可以在将文本分配给TextBox时使用转换器,在转换器中您可以根据网格的选定项返回值。你可以试试这个方法吗?如果已经尝试请忽略。
  • 请指定“多个单元格值”。您想从所有行选定行还是其他可能值的子集创建文本?
  • @grek40 抱歉,我编辑了这个问题。我实际上需要来自选定行和指定列的单元格的值(可能是 1 到 10000),但我需要所有这些值。我,然后将它们用作查询的输入参数。

标签: c# wpf xaml datagridcell


【解决方案1】:

这个想法是使用普通的Binding 和一个处理项目集合的转换器。使用MultiBinding 并不能真正用于绑定源项的动态集合。那么需要什么:

  • 带有项目的DataGrid,其中每个项目都包含一个特定的属性
  • 一个TextBox
  • TextBox.Text 属性上的Binding,其中来自DataGridSelectedItems 与转换器绑定以创建单个文本
  • Converter 接受项目集合并根据项目属性创建字符串
  • 一些更新逻辑,以确保在所选项目更新时更新文本

让我们从 xaml 开始,它可以很简单:

<Window.Resources>
    <local:ItemsToTextConverter x:Key="cItemsToTextConverter"/>
</Window.Resources>

<!-- your surrounding controls -->

<DataGrid x:Name="datagridbatch" SelectionChanged="datagridbatch_SelectionChanged"/>
<TextBox x:Name="input2" Text="{Binding ElementName=datagridbatch,Path=SelectedItems,Converter={StaticResource cItemsToTextConverter},Mode=OneWay}"/>

请注意,绑定仅以一种方式起作用 - 将字符串值分配回多个项目不像将项目压缩成单个字符串那么容易。

转换器需要获取一个项目集合并从属性中提取一个字符串:

public class ItemsToTextConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var items = value as IEnumerable;
        if (items != null)
        {
            // note: items may contain the InsertRow item, which is of different type than the existing items.
            // so the items collection needs to be filtered for existing items before casting and reading the property
            var items2 = items.Cast<object>();
            var items3 = items2.Where(x => x is MyItemType).Cast<MyItemType>();
            return string.Join(Environment.NewLine, items3.Select(x => x.UNIQUEPART_ID));
        }
        return string.Empty;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new InvalidOperationException();
    }
}

另外,DataGrid.SelectedItems 不会在选择更改时自动触发绑定更新,因此您需要在选择更改事件处理程序中触发手动更新:

void datagridbatch_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var binding = BindingOperations.GetBindingExpression(input2, TextBox.TextProperty);
    if (binding != null)
    {
        binding.UpdateTarget();
    }
}

【讨论】:

  • 我对这些代码行有几个问题: var items2 = items.Cast(); var items3 = items2.Where(x => x is MyItemType).Cast(); return string.Join(Environment.NewLine, items3.Select(x => x.UNIQUEPART_ID)); 1sr 问题:您所说的项目可能包含与现有项目不同类型的 InsertRow 项目是什么意思。 2.您是否过滤了上述行中的项目集合?如果是,你能详细说明一下吗?第三:MyItemType在代码行中做了什么:MyItemType).Cast();
  • (1) DataGrid.SelectedItems 可以包含一个允许创建新数据行的特殊项目,并且它具有特殊类型。因此,即使您的所有输入项都具有MyItemType 类型(这是编造的,因为您从未告诉我们DataGrid 中数据的类型名),您也不能假设SelectedItems 中的所有项都具有该类型.这就是为什么我在投射之前按类型过滤项目的原因。 Where 方法在 IEnumerable&lt;T&gt; 上可用,但在 IEnumerable 上不可用,所以我首先将所有项目转换为 object。圣诞节结束时可以写更多解释;)
猜你喜欢
  • 2021-10-23
  • 2019-08-15
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2013-12-27
  • 2014-12-31
相关资源
最近更新 更多