ListBox数据与包含字符串字符串int的List列表绑定

时间:2012-09-05 21:19:46

标签: c# windows-phone-7 data-binding listbox

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

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

我不想为行数据创建一个类,因此我没有Transaction类,并且不确定如何使用List列表进行绑定。我当然知道如果我是字符串字符串int或字符串int double。

1 个答案:

答案 0 :(得分:0)

您是否不想为您的行创建类类型?在使用XAML时,这将使您的生活更轻松。

为您的行创建一个类类型,并使其实现INotifyPropertyChanged。一旦您的类实现了INotifyPropertyChanged,就很容易在您的视图中绑定它。

假设您正在遵循MVVM模式。这意味着您将拥有一个View(您在XAML中编码)和一个ViewModel。此视图模型也将成为实现INotifyPropertyChanged的类。在视图的构造函数中,您将DataContext属性设置为ViewModel类的新实例。

现在列表部分。在ViewModel中,创建一个ObservableCollection<MyRow>ObservableCollection<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。

查看代码背后

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 );
        }
     }
}