Найти элементы, сгенерированные DataTemplate - PullRequest
0 голосов
/ 03 января 2012

Я изменяю свойство элемента TextBlock IsEnabled списка, как показано ниже

    <ListBox Name="myListBox" ItemTemplate="{StaticResource myDataTemplate}"
     IsSynchronizedWithCurrentItem="True">
      <ListBox.ItemsSource>
      <Binding Source="{StaticResource InventoryData}" XPath="Books/Book"/>
      </ListBox.ItemsSource>
   </ListBox>

В ListBox используется следующий шаблон данных как

   <DataTemplate x:Key="myDataTemplate">
      <TextBlock Name="textBlock" FontSize="14" Foreground="Blue">
      <TextBlock.Text>
     <Binding XPath="Title"/>
     </TextBlock.Text>
     </TextBlock>
   </DataTemplate>


 // Getting the currently selected ListBoxItem
 // Note that the ListBox must have
 // IsSynchronizedWithCurrentItem set to True for this to work
   ListBoxItem myListBoxItem =
  (ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items.CurrentItem));

 // Getting the ContentPresenter of myListBoxItem
 ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(myListBoxItem);

 // Finding textBlock from the DataTemplate that is set on that ContentPresenter
    DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
   TextBlock myTextBlock = (TextBlock)myDataTemplate.FindName("textBlock", myContentPresenter);
   // Do something to the DataTemplate-generated TextBlock
   myTextBlock.IsEnabled=false;


   private childItem FindVisualChild<childItem>(DependencyObject obj)
    where childItem : DependencyObject
   {
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
      {
      DependencyObject child = VisualTreeHelper.GetChild(obj, i);
      if (child != null && child is childItem)
        return (childItem)child;
       else
       {
        childItem childOfChild = FindVisualChild<childItem>(child);
        if (childOfChild != null)
            return childOfChild;
        }
      }
       return null;
   }


Но как я могу установить isEnabled = false; для всех текстовых блоков в этом списке?

Ответы [ 2 ]

3 голосов
/ 03 января 2012

Не делай этого.Если есть виртуализация, контейнеры для некоторых элементов даже не будут там, и вам придется иметь дело с довольно грязным кодом, чтобы обойти эту проблему.Попробуйте вместо этого связать IsEnabled и соответственно установить свойство / XML-атрибут.

2 голосов
/ 03 января 2012

Просто переберите все элементы списка с помощью цикла foreach и сделайте то же самое, что вы уже делаете для одного элемента

foreach (ListBoxItem item in yourListBox.Items)
        {
        // Getting the ContentPresenter of myListBoxItem
        ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(item );    
        // Finding textBlock from the DataTemplate that is set on that ContentPresenter
        DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
        TextBlock myTextBlock = (TextBlock)myDataTemplate.FindName("textBlock", myContentPresenter);
        // Do something to the DataTemplate-generated TextBlock
        myTextBlock.IsEnabled=false;
        }

НО

это не рекомендуемый подход для этого. Вместо этого вы должны использовать привязки для этой цели

Создайте свойство типа bool в вашем items source и bind textbox IsEnabled property с ним. Когда вы хотите disable/enable, текстовое поле просто изменит это свойство bool, и textbox будет автоматически enabled or disabled на основе значения bool

 <TextBlock Name="textBlock" IsEnabled="{Binding path=SomeBoolProperty"} FontSize="14" Foreground="Blue">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...