【问题标题】:Is there something similar to TabControlRegionAdapter.ItemContainerStyle Attached Property for ItemsControl?是否有类似于 ItemsControl 的 TabControlRegionAdapter.ItemContainerStyle 附加属性的东西?
【发布时间】:2012-01-18 10:14:41
【问题描述】:

我正在使用带有 Silverlight 的 Prism 4,并且我想使用 ItemsControl 来托管多个视图。我真的希望所有视图都包含在指定的 ItemTemplate 中,或者能够指定 ItemStyle,以便我可以使用类似 Silverlight Toolkit 中的 Expander 控件。当我尝试指定 ItemTemplate 时,会在运行时引发未处理的 System.NotSupportedException。

ItemsControl.Items must not be a UIElement type when an ItemTemplate is set.
   at System.Windows.Controls.ItemsControl.MS.Internal.Controls.IGeneratorHost.GetContainerForItem(Object item, DependencyObject recycledContainer)
   at System.Windows.Controls.ItemContainerGenerator.Generator.GenerateNext(Boolean stopAtRealized, Boolean& isNewlyRealized)
   at System.Windows.Controls.ItemContainerGenerator.System.Windows.Controls.Primitives.IItemContainerGenerator.GenerateNext(Boolean& isNewlyRealized)
   at System.Windows.Controls.ItemsControl.AddContainers()
   at System.Windows.Controls.ItemsControl.RecreateVisualChildren(IntPtr unmanagedObj)

代码

<ItemsControl Regions:RegionManager.RegionName="DetailsRegion">
     <ItemsControl.ItemTemplate>
        <DataTemplate>
           <Border BorderBrush="Red" BorderThickness="1">
              <ContentPresenter Content="{Binding}"/>
           </Border>
        </DataTemplate>
     </ItemsControl.ItemTemplate>
  </ItemsControl>

【问题讨论】:

  • 如何设置 ItemsSource?基于异常,听起来您正在将项目显式添加到项目控件 (itemsControl.itemsControl.Items.Add()) 而不是设置 ItemsSource,通常通过绑定或您可以通过 Codebehind (itemscontrol.ItemsSource =我的收藏)。
  • 我没有在 Xaml 中设置 ItemsSource。我在 Prism4 中使用默认的 ItemsControlRegionAdapter。它将 void Adapt(IRegion region, ItemsControl regionTarget) 中的 ItemsSource 设置为:regionTarget.ItemsSource = region.Views。 region.Views 是 IViewsCollection : IEnumerable, INotifyCollectionChanged。这里没有什么太疯狂的事情......
  • 你知道收藏中有什么吗?我认为这可能是问题所在,因为 SL 知道这已经是一个元素,它可能只是尝试渲染它而不是将其用作 DataTemplate 的 DataContext。
  • 你的意思是什么是'in'集合?抛出异常时,集合中没有任何内容。
  • 对不起,我的意思是“在”。看起来 PRISM 正在为该系列添加一些东西。例外显然是指一个项目。你能以某种方式订阅 CollectionChange 事件吗?我认为您将不得不编写自己的 IRegion 将元素包装到另一个内容中。

标签: silverlight-4.0 prism-4


【解决方案1】:

自从我使用 PRISM 以来已经有一段时间了,但以下是一个示例,您可以使用它来实现一个自定义 IRegion,该 IRegion 在将元素添加到集合之前对其进行包装。

public class RegionWrapper : Region
{
    public override Microsoft.Practices.Composite.Regions.IRegionManager Add(object view, string viewName, bool createRegionManagerScope)
    {
        var myWrapper = new Wrapper();
        myWrapper.Content = view;
        return base.Add(myWrapper, viewName, createRegionManagerScope);
    }
}

要注册此项目,您需要创建一个区域工厂,在 PRISM 中他们称之为适配器

public class RegionWrapperAdapter : RegionAdapterBase<IRegionAdapter>
{
    protected override Microsoft.Practices.Composite.Regions.IRegion CreateRegion()
    {
        return new RegionWrapper();
    }
}

然后在你的 Bootstrap 上注册你的适配器

    protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
    {
        var regionAdapterMappings = base.ConfigureRegionAdapterMappings();
        regionAdapterMappings.RegisterMapping(typeof(ItemsControl), Container.Resolve<RegionWrapperAdapter>());
        return regionAdapterMappings;
    }

当然,剩下的另一部分是实现控件“包装器”,以便您可以创建该类并添加内容。它可能只是一个 ContentControl,其特定样式类似于您在本示例中的样式,或者添加任何更花哨的东西。

此代码基于旧版本的 PRISM,因此最近可能发生了变化。

希望对你有帮助

米格尔

【讨论】:

  • 感谢@Miguel Madero 的回答。我会试试这个并回复你。
猜你喜欢
  • 2011-02-27
  • 2013-02-02
  • 2018-04-13
  • 2011-12-04
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多