首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ContentPresenter从ItemsControl返回null

ContentPresenter从ItemsControl返回null
EN

Stack Overflow用户
提问于 2021-02-23 09:03:40
回答 2查看 160关注 0票数 0

我想从ItemsControl中获取所有UI项。

在这篇文章中,How do I access the children of an ItemsControl?,我复制了一个答案,到目前为止,它是有效的。

但是,如果我直接在设置ItemsSource后在for-loop中执行代码(如下面的示例所示),那么contentpresenter就是null,我无法使用它。

如果我在很长一段时间后运行for-loop (也许当我按一下按钮时),一切都会很好。

如何在设置ItemsControl后直接访问ItemsSource的所有子级

代码语言:javascript
复制
itemscontrol.ItemsSource = items; // items is a list
itemscontrol.ApplyTemplate(); // might refresh the itemscontrol

for (int i = 0; i < itemscontrol.Items.Count; i++)
{
    //                      ↓ this is null
    ContentPresenter contentpresenter = (ContentPresenter)itemscontrol.ItemContainerGenerator.ContainerFromItem(itemscontrol.Items[i]);
    //                      ↑ this is null

    contentpresenter.ApplyTemplate();

    StackPanel stackPanel = (StackPanel)contentpresenter.ContentTemplate.FindName("selectedStackpanel", contentpresenter);
    // do some stuff with the stackpanel
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-23 17:17:19

更好的解决方案是向项目模型添加相关属性,例如IsUserSelected属性。然后创建一个Style,您将其分配给ItemsControl.ItemContainerStyle。在这个Style中,您定义了一个在IsUserSelected上触发的触发器。

就是这样做的。不要处理生成器,检查每个项目是否生成。让框架为您完成此工作。

代码语言:javascript
复制
 <ListBox ItemsSource="{Binding Items}">
   <ListBox.ItemContainerStyle>
     <Style TargetType="ListBoxItem">

       <Style.Triggers>
         <DataTrigger Binding="{Binding IsUserSelected}"
                      Value="True">
           <Setter Property="Background" Value="Red" />
         </DataTrigger>
       </Style.Triggers>
     </Style>
   </ListBox.ItemContainerStyle>`enter code here`
 </ListBox>

由于代码隐藏文件中已经有一个属性HighlightId,所以可以使用IMultiValueConverterMultiBinding来根据值定义颜色:

MainWindow.xaml.cs

代码语言:javascript
复制
partial class MainWindow
{
  public static readonly DependencyProperty HighlightIdProperty = DependencyProperty.Register(
    "HighlightId",
    typeof(int),
    typeof(MainWindow),
    new PropertyMetadata(default(int)));

  public int HighlightId
  {
    get => (int) GetValue(MainWindow.HighlightIdProperty);
    set => SetValue(MainWindow.HighlightIdProperty, value);
  }
}

HighlightIdToBrushConverter.cs

代码语言:javascript
复制
public class HighlightIdToBrushConverter : IMultiValueConverter
{
  public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
  {
    if (!(values[0] is MyModelType currentItem 
      && values[1] is int highlightId))
    {
      return Binding.DoNothing;
    }
    
    var highlightBrush = highlightId == currentItem.Id
      ? new SolidColorBrush(Colors.Red)
      : new SolidColorBrush(Colors.Transparent);
      
     highlightBrush.Freeze();
     return highlightBrush; 
  }

  public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) =>
    throw new NotSupportedException();
}

MainWindow.xaml

代码语言:javascript
复制
<ListBox ItemsSource="{Binding Items}">
  <ListBox.Resources>
    <HighlightIdToBrushConverter x:Key="HighlightIdToBrushConverter" />
  </ListBox.Resources>

  <ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
      <Setter Property="Background">
        <Setter.Value>
          <MultiBinding Converter="{StaticResource HighlightIdToBrushConverter}">
            <Binding />
            <Binding RelativeSource="{RelativeSource AncestorType=Window}" 
                     Path="HighlightId" />
          </MultiBinding>
        </Setter.Value>
      </Setter>
    </Style>
  </ListBox.ItemContainerStyle>
</ListBox>
票数 1
EN

Stack Overflow用户

发布于 2021-02-25 19:55:28

也许不是最好的编码风格,但它的工作可靠。

代码语言:javascript
复制
public ClassConstructor()
{
    InitializeComponent();
    itemscontrol.ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;
}

...

void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
    if (itemscontrol.ItemContainerGenerator.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
    {
        for (int i = 0; i < itemscontrol.Items.Count; i++)
        {
            ContentPresenter contentpresenter = (ContentPresenter)itemscontrol.ItemContainerGenerator.ContainerFromItem(itemscontrol.Items[i]);
            contentpresenter.ApplyTemplate();
            StackPanel stackPanel = (StackPanel)contentpresenter.ContentTemplate.FindName("selectedStackpanel", contentpresenter);
            int ID = FindIDofSelectedItemFromStackpanel(stackPanel);

            if (highlightID == ID)
            {
                Border border = (Border)contentpresenter.ContentTemplate.FindName("border_models", contentpresenter);
                border.Background = (Brush)FindResource("brushAccent3");
            }
            else
            {
                Border border = (Border)contentpresenter.ContentTemplate.FindName("border_models", contentpresenter);
                border.Background = Brushes.White;
            }
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66330043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档