以下情况是:我有一个对象列表,每个对象都用ID号引用。我正在尝试根据对象的ID编号在listView的列中设置一个值:
<ListView Name="Listview1"
Itemsource="{Binding ObjectList}">
<ListView.View>
<GridView>
<GridViewColumn Header="Header1" DisplayMemberBinding="{Binding subObject.property}"/>
<GridViewColumn Header="Header2" DisplayMemberBinding="{Binding PropertyOfAnItemInAList"/>
</GridView>
</ListView.View>
</ListView>
对象列表是ViewModel中的属性,并证明了对listView的观察力进行处理。header1和header2绑定到观测值的项目中的属性,称为"对象列表"。
这一切都适合Header1。问题是header2需要从位于观测值汇票每个元素内部的列表中选择一个项目,并根据对象列表中引用项目的另一属性显示它。
那么我该怎么做?
我通过在" CurrentSelection"中的对象列表中设置一个变量来设法使其正常工作,然后在binting the binting iTerrist从tocketsource torke outource iTerrist iTerion inter the listView时,该变量被设置为:
public ObservableCollection<theObject> ObjectList {
get {
foreach (theObject obj in sourceCollection) {
obj.CurrentID = MyID;
}
return new ObservableCollection<theObject>sourceCollection // <-- secondary question: Is this the best way to send an observableCollection to a View???
}
}
但是,这感觉像是一个骇客,而不是最好的做法,所以还有另一种更好的方法来完成同一件事吗?
编辑:
这是我现在拥有的对象列表中的对象的片段。
public class ObjectInObjectList {
/* constructor and various properties snipped to save space */
private subObject subObj;
public int CurrentID {get; set;}
public SubObject {
get { return subObject; } // etc...
}
private SortedList<int,int> valuesIWantInSecondColumn
Public int PropertyOfAnItemInAList {
return valuesIWantInSecondColumn[currentID];
}
我将从对象中删除CurrentID属性。我不想在域对象中具有UI属性。我认为最好的解决方案是为该列使用多键点,并从ViewModel中给出SortedList和您的MyID值,请使用转换器从SortedList返回所选的项目。这样的东西(也假设列出的Combobox):
<ComboBox Grid.Column="0" ItemsSource="{Binding Ids}" SelectedItem="{Binding MyID}" />
<ListView Name="Listview1" Grid.Column="1" ItemsSource="{Binding ObjectList}">
<ListView.View>
<GridView>
<GridViewColumn Header="Header1" DisplayMemberBinding="{Binding subObject.property}"/>
<GridViewColumn Header="Header2" >
<GridViewColumn.DisplayMemberBinding>
<MultiBinding Converter="{StaticResource IDictionarySelector}">
<Binding Path="PropertyOfAnItemInAList" />
<Binding Path="DataContext.MyID" RelativeSource="{RelativeSource AncestorType={x:Type Window}}" />
</MultiBinding>
</GridViewColumn.DisplayMemberBinding>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
我测试了此代码,不得不将toString()调用添加到返回中,否则它给我带来了绑定错误,即文本块需要字符串值(感谢Snoop):
public class IDictionarySelector : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (values != null && values.Length == 2)
{
IDictionary idictionary = values[0] as IDictionary;
int? key = values[1] as int?;
if ((idictionary != null) && (key != null) && (idictionary.Contains(key)))
{
return idictionary[key].ToString();
}
}
return null;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
您只需要在ObjectInObjectList
类中的属性上实现INotifyPropertyChanged
接口即可。特别是,您需要告诉接口,当CurrentID
属性发生变化时,PropertyOfAnItemInAList
属性已更改:
public int CurrentID
{
get { return currentID; }
set
{
currentID = value;
NotifyPropertyChanged("CurrentID");
NotifyPropertyChanged("PropertyOfAnItemInAList");
}
}
每次更改CurrentID
属性时,此通知将更新UI中的PropertyOfAnItemInAList
属性,因此您不需要任何特殊的Binding
。