0

I'm having an issue where I have made a user control with two content collections in it. for simplicities sake we'll say its two items controls.

in the code behind I am exposing those itemCollections so that I can actually declare the content in another control.

for example

<!-- 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> 

This actually works great with one small problem. As soon as I try to name any of the controls I get the following error.

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

Cannot set Name attribute value 'txt' on element 'TextBox'. 'TextBox' is under the scope of element 'TwoControls', which already had a name registered when it was defined in another scope.

If I didn't actually have to name the controls I wouldn't. We have some tools that run expecting certain content controls to be named so as part of the build process I need them to have names. Its also worth noting that I actually have a couple of events tied up in my TwoControls class, if I were to extract that to a data template I think I could make it work but I would have to work at it a bit more than currently.

Any input on why this is would be great.

1

1 Answer 1

1

I do not want to sound blunt, but whenever I got this particular namescope problem, I remember I was doing things more the Winforms way than the WPF way. I use the Usercontrols more for pagelike controls than for containerlike controls.

A suggestion might be to create a custom control instead of a usercontrol.

 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> 
Sign up to request clarification or add additional context in comments.

1 Comment

nothing blunt there, this is essentially what I did end up doing. It was just as I said in my post, a little more work because I was handling quite a few events but it did work nicely once I was done.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.