我有一个数据列表,其中每一行都是字符串字符串 int。在移植 iOS 应用程序时,我的所有数据都来自 plist。我还有另一个列表,它是 string int double。
我正在使用本教程为列表框创建自己的行。
我不想为行数据创建一个类,所以我没有 Transaction 类,并且不确定如何使用 List 列表进行绑定。我当然会知道我是 string string int 还是 string int double。
我有一个数据列表,其中每一行都是字符串字符串 int。在移植 iOS 应用程序时,我的所有数据都来自 plist。我还有另一个列表,它是 string int double。
我正在使用本教程为列表框创建自己的行。
我不想为行数据创建一个类,所以我没有 Transaction 类,并且不确定如何使用 List 列表进行绑定。我当然会知道我是 string string int 还是 string int double。
您不想为您的行创建类类型的任何原因?使用 XAML 时,这将使您的生活轻松一百万倍。
为您的行创建一个类类型并使其实现INotifyPropertyChanged。一旦你的类实现INotifyPropertyChanged
了,就很容易在你的视图中绑定到它。
假设您遵循 MVVM 模式。这意味着您将拥有一个视图(您使用 XAML 进行编码)和一个 ViewModel。这个视图模型也将是一个实现的类INotifyPropertyChanged
。在视图的构造函数中,您将DataContext
属性设置为 ViewModel 类的新实例。
现在是列表部分。在 ViewModel 中,创建一个ObservableCollection<MyRow>
. AnObservableCollection<T>
也是一种集合类型,它也实现了INotifyPropertyChanged
. 或者在您的情况下,听起来您有这些项目的列表。如果这是真的,我建议用另一个自定义类封装列表。它使 MVVM 模式的绑定更加自然。您可以双重嵌套 ObservableCollection,但您必须决定它是否易于阅读和理解。例如,ObservableCollection<ObservableCollection<MyRow>>
. 在下面的示例中,我假设您创建了一个类 (MySet) 来保存行,而不是双嵌套列表。
public class MyRow : INotifyPropertyChanged
{
public event PropertyChanged;
private string _stringValue = string.Empty;
public string StringValue
{
get { return _stringValue; }
set
{
if( _stringValue != value )
{
_stringValue = value;
if( PropertyChanged != null )
{
PropertyChanged( this, new PropertyChangedEventArgs( "StringValue" ) );
}
}
}
}
// continue with the rest of your properties
}
public class MySet : INotifyPropertyChanged
{
public event PropertyChanged;
private ObservableCollection<MyRow> _rows = null;
public ObservableCollection<MyRow> Rows
{
get { return _rows; }
set
{
if( _rows != value )
{
_rows = value;
if( PropertyChanged != null )
{
PropertyChanged( this, new PropertyChangedEventArgs( "Rows" ) );
}
}
}
}
}
public class MyViewModel : INotifyPropertyChanged
{
public event PropertyChanged;
private ObservableCollection<MySet> _rowSets = null;
public ObservableCollection<MySet> RowSets
{
get { return _rowSets; }
set
{
if( _rowSets != value )
{
_rowSets = value;
if( this.PropertyChanged != null )
{
this.PropertyChanged( this, new PropertyChangedEventArgs( "RowSets" ) );
}
}
}
}
}
现在在您的 XAML 中,您可以选择如何显示列表的嵌套性质。我推荐ItemsControl容器。您所要做的就是将 设置ItemsSource
为 ViewModel 的属性名称,然后覆盖DataTemplate
. 如果这样做,那么每个项目都将具有内部列表的数据上下文。与另一个 ItemsControl 重复,然后您将让项目上下文等于每个内部项目 (MyRow)。
<ItemsControl
ItemsSource="{Binding Path=RowSets}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl
ItemsSource="{Binding Path=Rows}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding Path=StringValue, Mode=OneWay}"
Margin="5,0,0,0"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
并且不要忘记将视图的 DataContext 设置为 ViewModel。
public class View : UserControl
{
public View()
{
InitializeComponents();
this.DataContext = new ViewModel();
}
}
上面的代码未经测试,仅让您大致了解如何使用它。
如果您不想创建一个类而只是绑定到一个数组,您也可以这样做。绑定路径允许索引器语法。您可以输入 XAML Text="{Binding Path=MyArray[0]}"
。
如果您有一个数组数组,则 XAML 可能如下所示:
<ItemsControl ItemsSource="{Binding Path=MyOuterArray}">
<ItemsControl.ItemTemplate>
<!-- The data context here is the inner array so the indexer are applied to the inner array -->
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=[0]}" />
<TextBlock Text="{Binding Path=[1]}" />
<TextBlock Text="{Binding Path=[2]}" />
</StackPanel>
</ItemsControl.ItemTemplate>
</ItemsControl>
其他几个选项是使用转换器将数组中的值转换为某种字符串格式,或者在负责适当格式化成员的行类上提供一个属性。您只是将数组元素打印为序列中的字符串吗?然后只需在名为“FormattedValue”的行类上创建一个自定义属性,并让它返回所有相关属性的 ToString() 连接。
public class MyRow : INotifyPropertyChanged
{
// ...
public string FormattedValue
{
get
{
return string.Join( ", ", this.MyArray );
}
}
}