Открытые ItemCollections, вызывающие сбой сборки при именовании содержимого - PullRequest
0 голосов
/ 09 марта 2012

У меня проблема с созданием пользовательского элемента управления с двумя коллекциями контента.для простоты мы скажем, что его элементы управления двумя элементами.

в коде позади Я выставляю эти 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"/>

Невозможно установить значение атрибута Name 'txt' для элемента 'TextBox'.«TextBox» находится в области действия элемента «TwoControls», имя которого уже зарегистрировано, когда оно было определено в другой области.

Если бы мне фактически не приходилось называть элементы управления, я бы не стал 'т.У нас есть некоторые инструменты, которые работают, ожидая, что определенные элементы управления содержимым будут названы, так что как часть процесса сборки мне нужно, чтобы у них были имена.Стоит также отметить, что у меня на самом деле есть пара событий, связанных в моем классе TwoControls, если бы мне пришлось извлечь это из шаблона данных, я думаю, что я мог бы заставить его работать, но мне пришлось бы работать над ним немного больше, чем сейчас.

Любая информация о том, почему это так, была бы замечательной.

1 Ответ

1 голос
/ 10 марта 2012

Я не хочу звучать тупо, но всякий раз, когда у меня возникала конкретная проблема с именной областью, я вспоминал, что я делал что-то больше в Winforms, чем в WPF.Я использую пользовательские элементы управления больше для элементов управления, подобных страницам, чем для контейнеров.

Можно предложить создать пользовательский элемент управления вместо пользовательского элемента управления.

    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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...