2
votes

in my Silverlight 4 application, I want to use an AutoCompleteBox from the Silverlight Toolkit. I use this AutoCompleteBox in a listbox, which items are defined in a 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>

To provide the suggested items to the AutoCompleteBox, I need to bind it on the ItemsSource property. The idea was to create the list in the constructor and then bind it to the AutoCompleteBox. But the AutoCompleteBox is just in the DataTemplate, so I cannot reference it directly.

Any idea, how to achieve that? I thought about something like "ItemsSource="{Binding SuggestionList"} but that would mean I'd need to create this list as a Property for the class of the objects that I bind to the list, which would be a big overhead.

Thanks in advance,
Frank

4

4 Answers

1
votes

I subscribed to the GotFocus-Event of the AutoCompleteBox and bind the list there. Thanks to Nathan and Shelby for putting my head towards the right direction!

0
votes

You should be able to traverse the tree by referencing the listbox in code something like:

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

but you might be better off creating the Binding in that constructor:

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 should give you that the root node of your ItemsTemplate and you should be able to cast that object to your AutoCompleteBox. If you had further embedded elements you would want to cast and attempt to get a container property for that element to continue further down into the template.

0
votes

try this. This has worked for me a dozen times.

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

that is, of course, if there is only one AutoCompleteBox in the listbox template, if it comes first, then try,

  FirstOrDefault();

at the end of your query.

Let me know if you need anything else.

0
votes

You can set the ItemsSource property of the AutoCompleteBox in a handler of its Loaded event (you'll get the AutoCompleteBox itself as the sender of the event).

xaml:

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

code behind:

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

Hope this helps