0

我有一个数据列表,其中每一行都是字符串字符串 int。在移植 iOS 应用程序时,我的所有数据都来自 plist。我还有另一个列表,它是 string int double。

我正在使用教程为列表框创建自己的行。

我不想为行数据创建一个类,所以我没有 Transaction 类,并且不确定如何使用 List 列表进行绑定。我当然会知道我是 string string int 还是 string int double。

4

1 回答 1

0

您不想为您的行创建类类型的任何原因?使用 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)。

视图的 XAML

<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。

View 背后的代码

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 );
        }
     }
}
于 2012-09-05T21:48:58.420 回答