加入收藏2到使用DataGrid的multibinding [英] Joining 2 collections into datagrid using multibinding
问题描述
我有数据的2集,第一个是仅适用于组名,第二个是值。
我想在一个DataGrid填补这些数据像这样的:
的groupId |组|商店1 |店内2 |店内3 |店内4
1 | GRP 1 | | | |
2 | GRP 2 | | | |
3 | GRP 3 | | | |
4 | GRP 4 | | | |
我在创建所需的行一个新的集合模型视图中创建一个新的属性。
然后我尝试使用multibinding和转换器像这样去实现它。
<&DataGrid的GT;
< DataGrid.Columns>
< DataGridTextColumn标题=的groupId绑定={结合的groupId}IsReadOnly =真/>
< DataGridTextColumn标题=组绑定={结合组名}IsReadOnly =真/>
< DataGridTextColumn标题=存储1绑定={结合S1}/>
< DataGridTextColumn标题=2店绑定={结合S2}/>
< DataGridTextColumn标题=3店绑定={结合S3}/>
< DataGridTextColumn标题=4店绑定={结合S4}/>
< /DataGrid.Columns>
< MultiBinding转换器={StaticResource的GroupsToValuesConverter}>
<绑定路径=组>< /装订>
<绑定路径=值>< /装订>
< / MultiBinding>
< / DataGrid的>
但得到这个错误。
更多信息:A'MultiBinding'无法在
'ItemCollection集合中使用。 A'MultiBinding'只能在DependencyObject的一个
的DependencyProperty进行设置。
块引用>
我相信它可以通过这个来完成的方式,但在这里缺少的一个步骤。
我对WPF太新,所以我感谢你的帮助。
公共对象转换(对象[]值类型TARGETTYPE,对象参数,System.Globalization.CultureInfo文化)
{
&的ObservableCollection LT; GroupStoreRow> retValue =新的ObservableCollection< GroupStoreRow>();
IEnumerable的<组>基=(IEnumerable的&所述;组>)值[0];
商店O =(店)值[1];
的foreach(在组人组)
{
INT的GroupId =(INT)group.GroupId;
GroupStoreRow C =新GroupStoreRow(的GroupId,group.Name,group.SortOrder);
如果(O!= NULL)
{
如果(o.Store1.ContainsKey(的groupId))
{
c.Amount1 =(int)的o.Store1 [的groupId] .Amount;
c.Capacity1 =(int)的o.Store1 [的groupId] .Capacity;
}
如果(o.Store2.ContainsKey(的groupId))
{
c.Amount2 =(int)的o.Store2 [的groupId] .Amount;
c.Capacity2 =(int)的o.Store2 [的groupId] .Capacity;
}
如果(o.Store3.ContainsKey(的groupId))
{
c.Amount3 =(int)的o.Store3 [的groupId] .Amount;
c.Capacity3 =(int)的o.Store3 [的groupId] .Capacity;
}
}
retValue.Add(三);
}
返回retValue;
}
公共对象[] ConvertBack(对象的值,类型[] targetTypes,对象参数,CultureInfo的文化)
{
抛出新NotImplementedException();
}
和这个GroupStoreRow类
类GroupStoreRow:BindableBase
{
私人布尔hasChanged = FALSE;
私人诠释_amount1,_capacity1;
私人诠释_amount2,_capacity2;
私人诠释_amount3,_capacity3;
公众诠释组ID {搞定;私人集; }
公共字符串组名{获得;私人集; }
公众诠释SortOrder的{搞定;私人集; }
公共GroupStoreRow(INT的groupId,串组名,INT中将sortOrder)
{
组ID =的groupId;
组名=组名;
SortOrder的=中将sortOrder;
}
公众诠释Amount1
{
{返回_amount1; }
组
{
的SetProperty(REF _amount1,价值);
}
}
公共小数容量1
{
{返回_capacity1; }
组
{
的SetProperty(REF _capacity1,价值);
}
}
...
公共BOOL更改
{
得到
{
返回hasChanged;
}
}
保护覆盖BOOL的SetProperty< T>(REF T存储,T值,[CallerMemberName]字符串参数propertyName = NULL)
{
布尔的returnValue = base.SetProperty< T>(REF存储,价值,propertyName的);
如果(的returnValue)
{
如果
hasChanged =真(hasChanged!);
}
返回的returnValue;
}
}
解决方案您可以设置
的ItemsSource
与MultiBinding
。所以你可以这样写<&DataGrid的GT;
< DataGrid.ItemsSource>
< MultiBinding转换器={StaticResource的MyMultiValConverter}>
<绑定路径=对象/>
<绑定路径=Objects2/>
< / MultiBinding>
< /DataGrid.ItemsSource>
< / DataGrid的>
和你应该仔细写
MultiValuesConverter
才达到预期的效果。例如,它可以是这样的(刚刚加盟两个集合)。其中,OwnObject
是我的ViewModel公共类DGMultiValueConverter:IMultiValueConverter
{
#地区IMultiValueConverter会员
公共对象转换(对象[]值类型TARGETTYPE,对象参数,
CultureInfo的文化)
{
的ObservableCollection< OwnObject> combinedCollection =
新的ObservableCollection< OwnObject>();
的foreach(中值VAR项[0]作为的ObservableCollection< OwnObject>)
{
combinedCollection.Add(项目);
}
的foreach(中值VAR项目[1]的ObservableCollection< OwnObject>)
{
combinedCollection.Add(项目);
}
返回combinedCollection;
}
公共对象[] ConvertBack(对象的值,类型[] targetTypes,对象参数,
CultureInfo的文化)
{
抛出新NotImplementedException( );
}
#endregion
}
I have 2 collections of data, the first one is only for group names and the second one is for values.
I want to fill these data in a datagrid like this:
groupId | group | store 1 | store 2 | store 3 | store 4 1 | grp 1 | | | | 2 | grp 2 | | | | 3 | grp 3 | | | | 4 | grp 4 | | | |
I created a new property in the modelview which creating a new collection of the required rows.
Then I tried to achieve it using multibinding and converters like this.
<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>
But got this error.
Additional information: A 'MultiBinding' cannot be used within a 'ItemCollection' collection. A 'MultiBinding' can only be set on a DependencyProperty of a DependencyObject.
I believe it can be done by this way but missing a step here.
I am so new for WPF so I appreciate your help.
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(); }
and this GroupStoreRow class
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; } }
解决方案You can set
ItemsSource
withMultiBinding
. So you can write something like this.<DataGrid> <DataGrid.ItemsSource> <MultiBinding Converter="{StaticResource MyMultiValConverter}"> <Binding Path="Objects" /> <Binding Path="Objects2" /> </MultiBinding> </DataGrid.ItemsSource> </DataGrid>
And you should carefully write
MultiValuesConverter
to achive desired effect. For example it can be like this (just joining two collections). WhereOwnObject
is my 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 }
这篇关于加入收藏2到使用DataGrid的multibinding的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!