c# - 使用多重绑定(bind)将 2 个集合连接到数据网格中

标签 c# wpf ivalueconverter multibinding

我有 2 个数据集合,第一个仅用于组名称,第二个用于值。

我想将这些数据填充到数据网格中,如下所示:

groupId  |  group  | store 1 | store 2 | store 3 | store 4
   1     |  grp 1  |         |         |         |
   2     |  grp 2  |         |         |         |
   3     |  grp 3  |         |         |         |
   4     |  grp 4  |         |         |         |

我在模型 View 中创建了一个新属性,它创建了所需行的新集合。

然后我尝试使用多重绑定(bind)和转换器来实现它。

<DataGrid>
   <DataGrid.Columns>
      <DataGridTextColumn Header="groupId" Binding="{Binding groupId}" IsReadOnly="True" />
      <DataGridTextColumn Header="group" Binding="{Binding groupName}" IsReadOnly="True" />
      <DataGridTextColumn Header="store 1" Binding="{Binding s1}" />
      <DataGridTextColumn Header="store 2" Binding="{Binding s2}" />
      <DataGridTextColumn Header="store 3" Binding="{Binding s3}" />
      <DataGridTextColumn Header="store 4" Binding="{Binding s4}" />
    </DataGrid.Columns>

    <MultiBinding Converter="{StaticResource GroupsToValuesConverter}">
       <Binding Path="Groups"></Binding>
       <Binding Path="Values"></Binding>
    </MultiBinding>
</DataGrid>

但出现此错误。

Additional information: A 'MultiBinding' cannot be used within a 'ItemCollection' collection. A 'MultiBinding' can only be set on a DependencyProperty of a DependencyObject.

我相信可以通过这种方式完成,但这里缺少一个步骤。

我是 WPF 新手,因此非常感谢您的帮助。

public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    ObservableCollection<GroupStoreRow> retValue = new ObservableCollection<GroupStoreRow>();

    IEnumerable<Group> groups = (IEnumerable<Group>)values[0];
    Store o = (Store)values[1];
    foreach (Person group in groups)
    {
        int GroupId = (int)group.GroupId;
        GroupStoreRow c = new GroupStoreRow(GroupId, group.Name, group.SortOrder);
        if (o != null)
        {
            if (o.Store1.ContainsKey(groupId))
            {
                c.Amount1 = (int)o.Store1[groupId].Amount ;
                c.Capacity1 = (int)o.Store1[groupId].Capacity ;
            }
            if (o.Store2.ContainsKey(groupId))
            {
                c.Amount2 = (int)o.Store2[groupId].Amount ;
                c.Capacity2 = (int)o.Store2[groupId].Capacity ;
            }
            if (o.Store3.ContainsKey(groupId))
            {
                c.Amount3 = (int)o.Store3[groupId].Amount ;
                c.Capacity3 = (int)o.Store3[groupId].Capacity ;
            }
        }
        retValue.Add(c);
    }
    return retValue;
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
    throw new NotImplementedException();
}

和这个 GroupStoreRow 类

class GroupStoreRow : BindableBase
{

    private bool hasChanged = false;
    private int _amount1, _capacity1;
    private int _amount2, _capacity2;
    private int _amount3, _capacity3;


    public int GroupID { get; private set; }
    public string GroupName { get; private set; }
    public int SortOrder { get; private set; }

    public GroupStoreRow(int groupId, string groupName, int sortOrder)
    {
        GroupID = groupId;
        GroupName = groupName;
        SortOrder = sortOrder;
    }

    public int Amount1
    {
        get { return _amount1; }
        set
        {
            SetProperty(ref _amount1, value);
        }
    }
    public decimal Capacity1
    {
        get { return _capacity1; }
        set
        {
            SetProperty(ref _capacity1, value);
        }
    }
    ...
    public bool Changed
    {
        get
        {
            return hasChanged;
        }
    }

    protected override bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        bool returnValue = base.SetProperty<T>(ref storage, value, propertyName);
        if (returnValue)
        {
            if (!hasChanged)
                hasChanged = true;
        }
        return returnValue;
    }
}

最佳答案

您可以使用MultiBinding设置ItemsSource。所以你可以写这样的东西。

<DataGrid>
    <DataGrid.ItemsSource>
        <MultiBinding Converter="{StaticResource MyMultiValConverter}">
            <Binding Path="Objects" />
            <Binding Path="Objects2" />
        </MultiBinding>
    </DataGrid.ItemsSource>
</DataGrid>

并且您应该仔细编写MultiValuesConverter以达到所需的效果。例如,它可以是这样的(只需连接两个集合)。其中 OwnObject 是我的 viewModel。

public class DGMultiValueConverter : IMultiValueConverter
{
    #region IMultiValueConverter Members

    public object Convert( object[] values, Type targetType, object parameter, 
                           CultureInfo culture )
    {
        ObservableCollection<OwnObject> combinedCollection = 
           new ObservableCollection<OwnObject>();
        foreach ( var item in values[0] as ObservableCollection<OwnObject> )
        {
            combinedCollection.Add( item );
        }
        foreach ( var item in values[1] as ObservableCollection<OwnObject> )
        {
            combinedCollection.Add( item );
        }
        return combinedCollection;
    }

    public object[] ConvertBack( object value, Type[] targetTypes, object parameter,
                                 CultureInfo culture )
    {
        throw new NotImplementedException();
    }

    #endregion
}

关于c# - 使用多重绑定(bind)将 2 个集合连接到数据网格中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35910578/

相关文章:

c# - 我想比较 2 个哈希集并找出差异

c# - 事件处理程序中抛出的 WPF 异常被吞噬了吗?

c# - 未找到与 RestoreAssemblyResources AssemblyName 元数据匹配的引用

c# - 在ViewModel(MVVM)内部使用 View 方法

c# - 在 WPF DataGrid 中格式化可为空的日期时间

c# - silverlight 中的动态图像源绑定(bind)

wpf - 异常 : 'IValueConverter' type does not have a public TypeConverter class

c# - Web 服务方法签名更改为数据类型字符串 [] 的请求/响应对象

.net - 如何在 WPF 中检测鼠标双击左键?

c# - 存储连接字符串