开发者

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜