【问题标题】:How to bind to ItemsSource in DataTemplate?如何绑定到 DataTemplate 中的 ItemsSource?
【发布时间】:2011-12-09 10:35:25
【问题描述】:

在我的 Silverlight 4 应用程序中,我想使用 Silverlight Toolkit 中的 AutoCompleteBox。我在列表框中使用此 AutoCompleteBox,其中项目在 DataTemplate 中定义

<ListBox x:Name="ListBoxCharacteristics">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <Grid Background="{StaticResource SolidBrushVeryLightGrey}">
        <sdk:AutoCompleteBox Text="{Binding Name, FallbackValue=[None], Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" IsTextCompletionEnabled="True"/>
      </Grid>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

要将建议的项目提供给 AutoCompleteBox,我需要将其绑定到 ItemsSource 属性。想法是在构造函数中创建列表,然后将其绑定到 AutoCompleteBox。但是 AutoCompleteBox 只是在 DataTemplate 中,所以我不能直接引用它。

任何想法,如何实现?我想过类似“ItemsSource="{Binding SuggestionList"} 之类的东西,但这意味着我需要将此列表创建为我绑定到列表的对象类的属性,这将是一个很大的开销。

提前致谢,
弗兰克

【问题讨论】:

    标签: silverlight data-binding datatemplate


    【解决方案1】:

    我订阅了 AutoCompleteBox 的 GotFocus-Event 并将列表绑定在那里。感谢 Nathan 和 Shelby 让我朝着正确的方向前进!

    【讨论】:

    • 检查这个作为答案。这将为您赢得另一个徽章。很高兴在这里提供帮助。
    【解决方案2】:

    您应该能够通过在代码中引用列表框来遍历树:

    (ListBoxCharacteristics.ItemTemplate.VisualTree as AutoCompleteBox).ItemSource = your_new_list;
    

    但您最好在该构造函数中创建绑定:

    Binding B = new Binding();
    B.Mode = BindingMode.TwoWay;
    B.NotifyOnValidationErrors = true;
    B.FallbackValue = "[None]"; // not sure about this one
    B.ValidatesOnExceptions = true;
    B.Source = your_new_list;
    
    (ListBoxCharacteristics.ItemTemplate.VisualTree as AutoCompleteBox).SetBinding(AutoCompleteBox.TextProperty, B);
    

    ListBoxCharacteristics.ItemTemplate.VisualTree 应该为您提供 ItemsTemplate 的根节点,并且您应该能够将该对象转换为 AutoCompleteBox。如果您有更多嵌入的元素,您可能想要强制转换并尝试获取该元素的容器属性,以继续深入到模板中。

    【讨论】:

    • 嗨谢尔比,感谢您的提示!但正如我回复 Nathan 时,我的问题是调用构造函数(或我的 DataBinding 方法)时 VisualTree 不存在。我现在绑定 GotFocus 事件。
    【解决方案3】:

    试试这个。这对我有用了十几次。

     AutoCompleteBox autoComplete = Listbox.ItemTemplate.GetVisualDescendants().OfType<AutoCompleteBox>().SingleOrDefault();
     autoComplete.ItemsSource = theListYouHavePopulated;
    

    当然也就是如果列表框模板中只有一个AutoCompleteBox,如果是先来的,那就试试吧,

      FirstOrDefault();
    

    在查询结束时。

    如果您还需要什么,请告诉我。

    【讨论】:

    • 嗨内森,感谢您的回复!使用 Listbox.ItemTemplate.GetVisual... 时,我收到一条错误消息,指出“Reference”不是有效的“DependencyObject”。省略“ItemTemplate”部分时,它可以工作,但不返回任何对象,可能是因为它们尚未创建。在将列表框绑定到我的数据源后,我直接放置了代码,但似乎还没有创建可视化树。当我考虑迟到什么时候绑定它时,我想到了解决方案——这让一切变得如此简单以至于我很惭愧,以至于我之前没有想到:在盒子的 GotFocus-Event 处绑定列表!
    【解决方案4】:

    您可以在Loaded 事件的处理程序中设置AutoCompleteBoxItemsSource 属性(您将获得AutoCompleteBox 本身作为事件的发送者)。

    xaml:

    <sdk:AutoCompleteBox ...
                         Loaded="autoCompleteBox_Loaded"/>
    

    后面的代码:

    private void autoCompleteBox_Loaded(object sender, RoutedEventArgs e)
    {
        var autoCompleteBox = sender as AutoCompleteBox;
        autoCompleteBox.ItemsSource = SuggestionList; //the list you want to bind to
    }
    

    希望对你有帮助

    【讨论】:

    • 嗨,Abdou,感谢您添加这种可能性!如果列表对于 AutoCompleteBox 的生命周期是恒定的,这将是首选方法。就我而言,这个列表可能会发生变化的可能性很小,所以我使用 GotFocus-Event 来确保即使在这种情况下它也是正确的。
    猜你喜欢
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-29
    • 2015-06-27
    • 1970-01-01
    • 2014-02-15
    • 1970-01-01
    相关资源
    最近更新 更多