How come I can only have one instance of a Silverlight UserControl per page?
Its pretty lame, but I tried adding two UserControl
's to my Silverlight Page
, and I get an exception telling me (with extensive digging) that the same control name has been used to the visual tree twice. So the controls inside my UserControl
are named, so therefore I can include only one of this UserControl
into the Page
at a time. Is this true, or am I not realizing something? Has Microsoft truly given up on code-reuse? This is very lame.
Edits
For people who come here, I was getting this a System.Resources.MissingManifestResourceException exception. It took some time to figure out that the problem was ambiguous names in the visual tree. Hopefully this helps you. Below is the full exception text.
Further Edits
Here is my XAML:
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="HeaderText"
res:Strings.Assignment="Text=MachiningView_Name"/>
<sdk:TabControl Grid.Row="2">
<sdk:TabItem Header="Projects">
<ScrollViewer>
<Grid>
<controls:Organizer Margin="4" ItemsSource="{Binding ProjectSummaries}" Height="24" VerticalAlignment="Top">
<controls:Organizer.GroupDescriptions>
<controls:OrganizerGroupDescription res:Strings.Assignment="Text=NoGroupingText" IsDefault="True" />
<controls:OrganizerGroupDescription res:Strings.Assignment="Text=GroupOwnerEmailText">
<controls:OrganizerGroupDescription.GroupDescription>
<helpers:OwnerEmailGroupDescription />
</controls:OrganizerGroupDescription.GroupDescription>
</controls:OrganizerGroupDescription>
<controls:OrganizerGroupDescription res:Strings.Assignment="Text=GroupStoreNumberText">
<controls:OrganizerGroupDescription.GroupDescription>
<helpers:StoreNumberGroupDescription />
</controls:OrganizerGroupDescription.GroupDescription>
</controls:OrganizerGroupDescription>
</controls:Organizer.GroupDescriptions>
</controls:Organizer>
</Grid>
</ScrollViewer>
</sdk:TabItem>
<sdk:TabItem Header="Machine Queues">
<ScrollViewer>
<Grid>
<开发者_开发问答controls:Organizer Margin="4" ItemsSource="{Binding ProjectSummaries}" Height="24" VerticalAlignment="Top">
<controls:Organizer.GroupDescriptions>
<controls:OrganizerGroupDescription res:Strings.Assignment="Text=NoGroupingText" IsDefault="True" />
<controls:OrganizerGroupDescription res:Strings.Assignment="Text=GroupOwnerEmailText">
<controls:OrganizerGroupDescription.GroupDescription>
<helpers:OwnerEmailGroupDescription />
</controls:OrganizerGroupDescription.GroupDescription>
</controls:OrganizerGroupDescription>
<controls:OrganizerGroupDescription res:Strings.Assignment="Text=GroupStoreNumberText">
<controls:OrganizerGroupDescription.GroupDescription>
<helpers:StoreNumberGroupDescription />
</controls:OrganizerGroupDescription.GroupDescription>
</controls:OrganizerGroupDescription>
</controls:Organizer.GroupDescriptions>
</controls:Organizer>
</Grid>
</ScrollViewer>
</sdk:TabItem>
</sdk:TabControl>
</Grid>
And here is my user control's XAML:
<StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=UserControl}">
<sdk:Label Content="Page:" VerticalAlignment="Center" Margin="0,0,5,0"/>
<sdk:DataPager Name="_projectSummariesPager"
Margin="0,0,5,0"
DisplayMode="FirstLastPreviousNextNumeric"
Source="{Binding Path=ItemsSource}"
PageSize="10"/>
<ComboBox Name="_itemPerPageCombo"
Margin="0,0,5,0"
SelectionChanged="_itemPerPageCombo_SelectionChanged"
SelectedItem="{Binding Path=SelectedPageSize, Mode=TwoWay}"
SelectedValuePath="Value"
ItemsSource="{Binding Path=PageSizes}"/>
<ComboBox Name="_groupDescription"
Margin="0,0,5,0"
SelectionChanged="_groupDescription_SelectionChanged"
SelectedItem="{Binding Path=SelectedGroupDescription, Mode=TwoWay}"
ItemsSource="{Binding Path=GroupDescriptions}"/>
</StackPanel>
Names given to elements in Xaml need to be unique within the namescope. Each execution of LoadComponent creates a new namescope. Hence the names within the UserControl
will not conflict in the visual tree when multiple instances of the control were used.
So the answer to question as it stands right now is: because you are doing something wrong.
What the "something" is is unclear right now. Perhaps if you included your xaml in the question we can help you.
Edit
So reading between the lines this is what I'm guessing you are doing. You have a UserControl that has a number for properties and you want controls within the UserControl to bind to these properties so you are doing this:-
<StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=UserControl}">
This would indicate that you have added Name="UserControl"
to the <UserControl..
element at the top of its xaml.
I can't quite find a way to reproduce your problem but I am aware of problems with earlier versions of SL where this approach is a problem. Personally I think its better to avoid setting properties that really belong to the external consumer of the component (its up to the page that is using you UserControl what its name is and whether it should have name at all).
Hence my approach to solve this "Bind to the UserControl itself" sort of Problem:-
<StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=LayoutRoot.Parent}">
where LayoutRoot is the name of the top level Grid
which is the root of the UserControl content. This still binds to the UserControl itself via the Grid's Parent
property. However this does not require a name to be added to the UserControl itself in its own xaml.
When you add the UserControl, make sure to assign it a unique name, ie:
<Page ...
<StackPanel>
<local:YourUserControl x:Name="Foo" />
<!-- Make sure not to duplicate x:Name/Name here! -->
<local:YourUserControl x:Name="Bar" />
</StackPanel>
</Page>
精彩评论