【问题标题】:How does data binding work?数据绑定如何工作?
【发布时间】:2012-07-09 10:11:49
【问题描述】:

我现在正在尝试将数据添加到列表框中。如果您查看我的 XAML,这是我构建的列表框:

<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 类中:

public Search()
    {
        InitializeComponent();

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

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

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

【问题讨论】:

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


    【解决方案1】:

    我建议您通过 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
    

    【讨论】:

    • 好吧,现在更清楚了,所以基本上你只需将 listBox.ItemsSource() 设置为其他一些对象,然后包含 firstName 和 lastName 等。然后 listBox 会自动填充数据,我不必遍历 for 循环或类似的东西来填充列表?
    • 是的,您不需要使用任何类型的迭代
    • 你有那个教程吗?
    • @CodoSapien 检查它HERE
    【解决方案2】:

    值得注意的是,您当前的代码不起作用。

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

    例如

    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 做了什么,但可能是您需要在绑定中指定 Mode

    例如

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

    【讨论】:

    • “如果你在 ListBox 上设置 DataContext,所有的列表框子项都会看到这个 DataContext” 我知道你想说什么,但这是错误的。列表框的子项将其数据上下文设置为在绑定到列表框的 ItemsSource 属性的集合中找到的各个项目。更正确的说法是“如果您在 Grid 上设置 DataContext,则 Grid 的所有子级都将拥有此 DataContext”
    • 是的,你是对的,我想我只是想解释数据上下文是如何工作的,并选择了一个糟糕的控制示例(例如,除了 ItemsControl 之外的任何东西都会像你所说的那样更好)
    【解决方案3】:

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

    【讨论】:

    • 仅链接的答案不是好的答案。除非您要在此处解释解决方案并将链接用作资源 - 最好作为评论。
    • @Tomas Jansson - 不过还是感谢 Tomas,它确实让我更清楚了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2014-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-04
    相关资源
    最近更新 更多