当内容被命名时,暴露的 ItemCollections 导致构建失败

Posted

技术标签:

【中文标题】当内容被命名时,暴露的 ItemCollections 导致构建失败【英文标题】:Exposed ItemCollections causing build to fail when the content is named 【发布时间】:2012-03-27 00:17:37 【问题描述】:

我遇到了一个问题,我创建了一个包含两个内容集合的用户控件。为简单起见,我们将其称为两个项目控件。

在后面的代码中,我公开了这些 itemCollections,以便我可以在另一个控件中实际声明内容。

例如

<!-- User Control xaml -->
<UserControl>
   <StackPanel Orientation="Horizontal" >
       <ItemsControl x:Name="_itemsControl1" />
       <ItemsControl x:Name="_itemsControl2" />
   </StackPanel>
</UserControl>


//in the codebehind for user control
public partial class TwoControls 

    public ItemCollection ItemsOne  get  return _itemsControl1.Items; 
    public ItemCollection ItemsTwo  get  return _itemsControl2.Items; 



<!-- Using the control in xaml later -->
<Custom:TwoControls>    
    <Custom:TwoControls.ItemsOne>
        <TextBox />
        <TextBox />
        <TextBox />
        <TextBox />
        <TextBox />
    </Custom:TwoControls.ItemsOne>
    <Custom:TwoControls.ItemsTwo>
        <Button />
        <Button />
        <Button />
        <Button />
        <Button />
    </Custom:TwoControls.ItemsTwo>
<Custom:TwoControls>

这实际上对一个小问题很有效。一旦我尝试命名任何控件,我就会收到以下错误。

<!-- Using the control in xaml later -->
<Custom:TwoControls>    
    <Custom:TwoControls.ItemsOne>
        <TextBox x:Name="txt"/>

无法在元素“TextBox”上设置名称属性值“txt”。 “TextBox”在元素“TwoControls”的范围内,当它在另一个范围内定义时,它已经注册了一个名称。

如果我实际上不必为控件命名,我就不会。我们有一些工具在运行时期望某些内容控件被命名,因此作为构建过程的一部分,我需要它们具有名称。还值得注意的是,我实际上在我的 TwoControls 类中绑定了几个事件,如果我要将其提取到数据模板中,我认为我可以使它工作,但我必须比现在多做一点工作。

任何关于为什么会这样的意见都会很棒。

【问题讨论】:

这能回答你的问题吗? How to create a WPF UserControl with NAMED content 【参考方案1】:

我不想直言不讳,但每当我遇到这个特定的名称范围问题时,我记得我做事更多的是 Winforms 方式而不是 WPF 方式。我将 Usercontrols 更多地用于类似页面的控件,而不是类似容器的控件。

建议可能是创建自定义控件而不是用户控件。

    public class TwoControls: Control
    
      static TwoControls( )
      
        DefaultStyleKeyProperty.OverrideMetadata( typeof( TwoControls ) , new FrameworkPropertyMetadata( typeof( TwoControls ) ) );
      

      public ObservableCollection<UIElement> ItemsOne
      
        get  return ( ObservableCollection<UIElement> )GetValue( ItemsOneProperty ); 
        set  SetValue( ItemsOneProperty , value ); 
      
      public static readonly DependencyProperty ItemsOneProperty = DependencyProperty.Register( 
        "ItemsOne" , typeof( ObservableCollection<UIElement> ) , typeof( TwoControls ) , 
        new PropertyMetadata( new ObservableCollection<UIElement>( ) ) );

      public ObservableCollection<UIElement> ItemsTwo
      
        get  return ( ObservableCollection<UIElement> )GetValue( ItemsTwoProperty ); 
        set  SetValue( ItemsTwoProperty , value ); 
      
      public static readonly DependencyProperty ItemsTwoProperty = DependencyProperty.Register( 
        "ItemsTwo" , typeof( ObservableCollection<UIElement> ) , typeof( TwoControls ) , 
        new PropertyMetadata( new ObservableCollection<UIElement>( ) ) );
    
      //The next in your ResourceDictionary
     <Style xmlns:local="clr-namespace:WPFApplication1" TargetType="x:Type local:TwoControls">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="x:Type local:TwoControls">
            <StackPanel Orientation="Horizontal">
              <ItemsControl ItemsSource="Binding RelativeSource=RelativeSource Mode=TemplatedParent, Path=ItemsOne"/>
              <ItemsControl ItemsSource="Binding RelativeSource=RelativeSource Mode=TemplatedParent, Path=ItemsTwo"/>
            </StackPanel>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

    //The last in your xaml
    <Custom:TwoControls x:Name="twoControls1">
      <Custom:TwoControls.ItemsOne>
        <TextBox x:Name="Test1"/>
        <TextBox x:Name="Test2"/>
        <TextBox x:Name="Test3"/>
        <TextBox x:Name="Test4"/>
        <TextBox x:Name="Test5"/>
      </Custom:TwoControls.ItemsOne>
      <Custom:TwoControls.ItemsTwo>
        <Button x:Name="ButtonTest1"/>
        <Button x:Name="ButtonTest2"/>
        <Button x:Name="ButtonTest3"/>
        <Button x:Name="ButtonTest4"/>
        <Button x:Name="ButtonTest5"/>
      </Custom:TwoControls.ItemsTwo>
    </Custom:TwoControls>

【讨论】:

没什么直截了当的,这基本上就是我最终所做的。就像我在帖子中所说的那样,需要多做一些工作,因为我要处理很多事件,但是一旦我完成了它就可以很好地工作。

以上是关于当内容被命名时,暴露的 ItemCollections 导致构建失败的主要内容,如果未能解决你的问题,请参考以下文章

解压并重命名

在kubernetes上将host作为localhost暴露给节点js app

Drupal 视图 - 可以拆分暴露的表单吗?

当内部作用域不起作用时,为啥编译器不采用命名空间名称?

当消费者触发重建时,MaterialApp 主页小部件不会被渲染。需要油漆

python基础之了解函数多一点