Silverlight - 获取DataTemplate的ItemsControl

时间:2010-02-27 17:10:23

标签: silverlight

我有一个使用DataGrid的Silverlight应用程序。在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在DataGrid的DataTemplate中,我不相信我只能添加一个x:Name并从我的代码隐藏中引用它。或者有办法做到这一点吗?

谢谢!

4 个答案:

答案 0 :(得分:4)

使用ItemsControl.ItemsControlFromItemContainerVisualTreeHelper.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递归函数,以便更轻松地实现这一目标。

答案 1 :(得分:4)

我喜欢在我的app中的某个静态类中使用这个小扩展方法: -

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();

答案 2 :(得分:0)

不确定这是否适用,但这会使用相同的原则创建“切换按钮栏”。

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);
    }
}
}

答案 3 :(得分:0)

以下是捕获容纳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;
            }
        }

我希望有所帮助。