数据绑定如何工作?

时间:2012-07-09 10:11:49

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

我正在尝试将数据添加到listBox中。如果你看看我的XAML,这是我构建的listBox:

<ListBox 
            Height="517" 
            HorizontalAlignment="Left" 
            Margin="12,84,0,0" 
            Name="searchList" 
            VerticalAlignment="Top" 
            Width="438" 
            SelectionChanged="SearchList_SelectedEvent">

            <!-- What each listbox item will look like -->
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding firstName}" FontSize="28" />
                        <TextBlock Text="{Binding lastName}" FontSize="28" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>

</ListBox>

在我的.css类中,它与包含listBox的屏幕相关联:

public Search()
    {
        InitializeComponent();

        //The variables that I want to render in the list         
        string firstName = "John";
        string lastName = "Smith";
    }  

所以我的问题是,数据绑定究竟是如何工作的?您可以看到在XAML中我试图绑定变量,但我不知道这是否可行或者我是否正确执行?

对于初学者,XAML如何知道在哪里找到这些变量?

3 个答案:

答案 0 :(得分:2)

我建议你在另一个答案中通过Tomas Jansson建议的this tutorial。 除了你的代码,

首先,您需要创建一个List或ObservableCollection,其中包含可绑定到ListBox的数据。

List myList = new List()
          {new Name() { firstName = "sdfjsdk", lastName= "sdfsfsjdf"},
           new Name() { firstName = "bthbbh", lastName= "ereyyyu"},
           new Name() { firstName = "svbfbb", lastName= "sdfertbn"} };

其中名称是

class Name()
{
    string firstName;
    string lastName;
}

然后在代码后面,

myList.ItemsSource = myList; //this lets the XAML from where to fetch the data to bind

答案 1 :(得分:1)

值得注意的是,您当前的代码无效。

每个控件都存在于称为逻辑树的东西中。逻辑树是一个类似于控件层次结构的树,其中ListBox是此示例中的根 - 其中的控件是子控件。

e.g。

RootControl
|
|---| ChildOfRootControl
    |
    |----| ChildOfChildOfRootControl
    |    |
    |    | AnotherChildOfChildOfRootControl
    |
    | AnotherChildOfRootControl

每个控件都有一个DataContext属性 - 这个属性会自动从树根目录传播到所有子节点(例如,如果你在任何控件上设置DataContext,所有控件的子节点都会看到这个DataContext - 除了从ItemsControl派生的任何内容,其中子项通常具有绑定ItemsSource属性的DataContext。这个DataContext只在树下面传递给子节点 - 如果你在子控件的DataContext中放置一个新值,它将覆盖父类DataContext

DataContext是控件将绑定到的默认对象:即,如果未在绑定中指定任何其他参数,则DataContext将成为目标对象

Text="{Binding FirstName}"

上面的绑定会查看DataContext。为了绑定其他东西,你需要在绑定等中指定Source或ElementName

除了DataContext之外,还有一个名为ItemsControl的基本控件,大多数类似列表的控件都会继承该控件。

ItemsControl公开名为ItemsSource的属性,该属性指定将在控件中显示的项列表。这与DataContext的工作方式略有不同,因为您可以同时拥有DataContext和ItemsSource。

此外,ItemsControl中的任何子项(例如每个列表框项)都不会从其父控件继承DataContext,而是它们的DataContext将指向它们单独绑定的项。

示例 - 假设您将“MyObject”的DataContext分配给根控件(网格),并将“MyListOfObjects”分配给ListBox:

Grid (DataContext = MyObject)
|
|---| ListBox (DataContext = MyObject) (ItemsSource = MyListOfObjects)
    |
    |----| ListBoxItem (DataContext = MyListOfObjects[0])
    |    |
    |    | ListBoxItem (DataContext = MyListOfObjects[1])
    |    |
    |    | ListBoxItem (DataContext = MyListOfObjects[2])
    |    |
    |    | ListBoxItem (DataContext = MyListOfObjects[3])
    |
    | TextBox (DataContext = MyObject)

在您的情况下,ListBox.ItemsSource属性将为NULL,因此您的绑定路径将不起作用。当您运行此代码时,您很可能会在输出窗口中看到绑定表达式错误,因为绑定将评估为不存在的属性(实际上在这种情况下,您不会因为没有从ItemsSource创建的项目)

通常绑定到对象 - 例如业务对象,甚至绑定到页面上的其他控件。

因此,在您的情况下,您可能想要创建一个包含FirstName和LastName属性的对象。看起来好像你正在使用ListBox,你需要绑定这些项的集合 - 所以理想情况下你想要一个实现某种变更通知机制的集合。这可确保在列表更改时更新UI。

ObservableCollection实现了这一点 - 所以创建一个ObservableCollection并将它分配给ListBox上的ItemsSource应该可以工作。

值得注意的是,ObservableCollection的更改通知仅发生在列表级别 - (如果列表已更改,例如添加了一个项目),但不会发生在对象级别。如果您还希望对列表中包含的对象进行更改以反映在UI中,则需要对这些对象实施更改通知。这是通过实现INotifyPropertyChanged接口完成的。

最后 - 如果您希望能够编辑绑定,请确保在绑定中指定此绑定 - 默认情况下,Silverlight假定所有绑定都是只读的。我不确定Windows Phone 7的作用,但可能需要在绑定中指定模式

e.g。

Text="{Binding SomeText, Mode=TwoWay}"

答案 2 :(得分:0)

您是否尝试搜索它?这有希望解释了很多数据绑定的工作原理:http://jesseliberty.com/2010/11/10/windows-phone-from-scratch-6-data-binding-really/