Silverlight - получить ItemsControl для шаблона данных - PullRequest
3 голосов
/ 27 февраля 2010

У меня есть приложение Silverlight, которое использует DataGrid. Внутри этой DataGrid у меня есть DataTemplate, который определяется следующим образом:

<Grid x:Name="myGrid" Tag="{Binding}" Loaded="myGrid_Loaded">
  <ItemsControl ItemsSource="{Binding MyItems}" Tag="{Binding}">
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <StackPanel Orientation="Horizontal">
          <StackPanel Orientation="Horizontal" Width="138">
            <TextBlock Text="{Binding Type}" />
            <TextBox x:Name="myTextBox" TextChanged="myTextBox_TextChanged" />
          </StackPanel>
        </StackPanel>
      </DataTemplate>
    </ItemsControl.ItemTemplate>
  </ItemsControl>
</Grid>

Когда пользователь вводит текст в TextBox, у меня есть событие (myTextBox_TextChanged), которое должно быть запущено в этот момент. Когда это событие запускается, я хотел бы получить элемент ItemsControl, который является контейнером для этого TextBox. Как мне получить этот ItemsControl из моего обработчика событий?

Обратите внимание: поскольку ItemsControl находится в DataTemplate DataGrid, я не верю, что могу просто добавить x: Name и сослаться на него из своего кода. Или есть способ сделать это?

Спасибо!

Ответы [ 4 ]

4 голосов
/ 27 февраля 2010

Мне нравится иметь этот небольшой метод расширения в статическом классе где-то в моем приложении: -

public static IEnumerable<DependencyObject> Ancestors(this DependencyObject root)
{
    DependencyObject current = VisualTreeHelper.GetParent(root);
    while (current != null)
    {
        yield return current;
        current = VisualTreeHelper.GetParent(current);
    }
}

С этим вы сможете сделать что-то вроде этого: -

ItemsControl control = ((DependencyObject)sender).Ancestors()
    .TypeOf<ItemsControl>().FirstOrDefault();
4 голосов
/ 27 февраля 2010

Используя комбинацию ItemsControl.ItemsControlFromItemContainer и VisualTreeHelper.GetParent, вы сможете найти свой ItemsControl

var txt = sender as TextBox;
var panel1 = VisualTreeHelper.GetParent(txt);
var panel2 = VisualTreeHelper.GetParent(panel1);
var contentPresenter = VisualTreeHelper.GetParent(panel2);
var ic = ItemsControl.ItemsControlFromItemContainer(contentPresenter);

Вам также может понадобиться поискать в Интернете функции VisualTreeHelper Recursive, чтобы упростить эту задачу.

0 голосов
/ 03 марта 2011

Вот пример захвата контейнера, в котором находится элемент ItemsControl:

       CheckBox checkbox = sender as CheckBox;

        foreach (var item in MembersItemsControl.Items)
        {
            var container = MembersItemsControl.ItemContainerGenerator.ContainerFromItem(item) as FrameworkElement;

            UserInformation user = container.DataContext as UserInformation;

            bool isMale = true;
            if (user.sex == isMale && checkbox.IsChecked.Value == true)
            {
                container.Visibility = System.Windows.Visibility.Visible;
            }
        }

Надеюсь, это поможет.

0 голосов
/ 13 марта 2010

Не уверен, что это применимо, но это создает «переключающую панель кнопок», использующую те же принципы.

private void UIClassButton_Click(object sender, RoutedEventArgs e){
 Button SenderButton = (Button)sender;
 ItemsControl SendersItemControl = ItemsControl.ItemsControlFromItemContainer(VisualTreeHelper.GetParent(SenderButton));
 IEnumerable<DependencyObject> DependencyObjectCollection = SendersItemControl.GetContainers();

foreach (ContentPresenter item in DependencyObjectCollection) {
    ContentPresenter UIClassPresenter = (ContentPresenter)item;
    Button UIClassButton = (Button)UIClassPresenter.GetVisualChildren().First();
    if (UIClassButton != SenderButton) {
        VisualStateManager.GoToState(UIClassButton, "Normal", true);
    }
    else {
        VisualStateManager.GoToState(UIClassButton, "Pressed", true);
    }
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...