2012-06-12 2 views
2

В приложении WPF я создаю Listbox с его ItemTemplate определены в следующих DataTemplate в XAML:Доступ ListBoxItem-управления в WPF ListBox

<DataTemplate x:Key="ListItemTemplate"> 
    <Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"></RowDefinition> 
     <RowDefinition Height="*"></RowDefinition> 
    </Grid.RowDefinitions> 
    <StackPanel> 
     <Button/> 
     <Button/> 
     <Button Name="btnRefresh" IsEnabled="false"/> 
     <TextBlock/> 
     <TextBlock/> 
     <TextBlock/> 
     <TextBlock/> 
    </StackPanel> 
    <TextBox/> 
    </Grid> 
</DataTemplate> 

После ListBox генерируется мне нужно изменить следующую кнопку IsEnabled propety истина на всех ListBoxItem (ы): <Button Name="btnRefresh" IsEnabled="false"/>

ПРОБЛЕМА:

Я не могу получить доступ к ListBoxItem (s) и, следовательно, не могу получить доступ к своим детям с этой кнопкой среди них.

Есть ли в WPF ничего подобного ListBox.Descendents(), который находится в Silverlight или любым другим способом, чтобы добраться до этой кнопки,

+0

как вы связывании ItemsSource вашего ListBox? – jimmyjambles

+0

Я назначаю экземпляр объекта ItemSource программно, а затем использую Text = "{Binding Name}" для каждого элемента управления – Rafal

+0

Я все еще не совсем понимаю ваш вопрос, вы пытались привязать IsEnabled = "{Binding IsObjectEnabled}" и добавили, что аксессор к объекту вы заполняете список? – jimmyjambles

ответ

7

Предпочтительный способ сделать это, изменив свойство в ViewModel, который связан к свойству IsEnabled этого Button. Добавьте обработчик события ListBox.Loaded и установите это свойство в ViewModel равным false при загрузке ListBox.

Другой вариант, если вам нужно пройти через каждый данных шаблонного элемента в ListBox затем выполните следующие действия:

if (listBox.ItemContainerGenerator.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated) 
     { 
      foreach (var item in listBox.Items) 
      { 
       ListBoxItem container = listBox.ItemContainerGenerator.ContainerFromItem(item) as ListBoxItem; 
       // Get button 
       ContentPresenter contentPresenter = contentPresenter.ContentTemplate.FindName("btnRefresh", contentPresenter); 
       Button btn = contentPresenter as Button; 
       if (btn != null) 
        btn.IsEnabled = true; 
      } 
     } 
+0

Спасибо, что мне удалось отправить контейнер в listBoxItem, просто нужно найти кнопку внутри grid-> gridrow-> stackpanel – Rafal

+0

@Rafal Я добавил код, чтобы получить кнопку. Первый подход по-прежнему является предпочтительным способом MVVM. – evanb

+0

Я не нашел изменения кода работоспособными. См. [Как найти элементы, созданные с помощью DataTemplate] (http://msdn.microsoft.com/en-us/library/bb613579.aspx) – OmegaMan

1

Если все, что вам нужно, это позволяет кнопки в ListBoxItem, есть XAML решение , Использование DataTemplate.Triggers:

<DataTemplate.Triggers> 
    <DataTrigger Binding="{Binding RelativeSource= 
     {RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True"> 
     <Setter TargetName="btnRefresh" Property="IsEnabled" Value="true"/> 
    </DataTrigger> 
</DataTemplate.Triggers> 

Таким образом, всякий раз, когда выбрано ListBoxItem, будет включена кнопка по этому пункту. Нет кода C#. Простой и чистый.

Более подробную информацию можно найти по адресу: http://wpftutorial.net/DataTemplates.html