Почему у меня может быть только один экземпляр Silverlight UserControl на страницу? - PullRequest
2 голосов
/ 14 сентября 2011

Это довольно неубедительно, но я попытался добавить два UserControl к своему Silverlight Page, и я получил исключение, сообщающее мне (с обширным копанием), что одно и то же имя элемента управления дважды использовалось для визуального дерева. Таким образом, элементы управления внутри моего UserControl названы, поэтому я могу включать только один из этих UserControl в Page одновременно. Это правда или я чего-то не понимаю? Microsoft действительно отказалась от повторного использования кода? Это очень хромая.

редактирует

Для людей, которые приходят сюда, я получил исключение System.Resources.MissingManifestResourceException. Потребовалось некоторое время, чтобы понять, что проблема заключается в неоднозначных именах в визуальном дереве. Надеюсь, это поможет вам. Ниже приведен полный текст исключения.

Дополнительные правки

Вот мой 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>

А вот 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>

Ответы [ 2 ]

1 голос
/ 14 сентября 2011

Имена, данные элементам в Xaml, должны быть уникальными в пределах namescope .Каждое выполнение LoadComponent создает новую область имен.Следовательно, имена в UserControl не будут конфликтовать в визуальном дереве при использовании нескольких экземпляров элемента управления.

Таким образом, ответ на вопрос в том виде, в каком он сейчас существует, таков: потому что вы делаете что-то не так.

Что такое «что-то», сейчас неясно.Возможно, если вы включите свой xaml в вопрос, мы можем вам помочь.

Редактировать

Так что, читая между строк, я думаю, вы это делаете.У вас есть UserControl, у которого есть номер для свойств, и вы хотите, чтобы элементы управления в UserControl связывались с этими свойствами, поэтому вы делаете это: -

 <StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=UserControl}">  

Это будет означать, что вы добавили Name="UserControl" кЭлемент <UserControl.. вверху его xaml.

Я не могу найти способ воспроизвести вашу проблему, но я знаю о проблемах с более ранними версиями SL, где этот подход является проблемой.Лично я думаю, что лучше избегать установки свойств, которые действительно принадлежат внешнему потребителю компонента (вплоть до страницы, которая использует вас, UserControl, каково его имя и должно ли оно вообще иметь имя).

Отсюда мой подход к решению этой проблемы «Привязать к самому UserControl»: -

 <StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=LayoutRoot.Parent}">

, где LayoutRoot - это имя верхнего уровня Grid, являющегося корнем содержимого UserControl.Это все еще привязывается к самому UserControl через свойство Grid Parent.Однако для этого не требуется добавлять имя в сам UserControl в своем собственном xaml.

0 голосов
/ 14 сентября 2011

Когда вы добавляете UserControl, обязательно присвойте ему уникальное имя, например:

<Page ...
    <StackPanel>
         <local:YourUserControl x:Name="Foo" />
         <!-- Make sure not to duplicate x:Name/Name here! -->
         <local:YourUserControl x:Name="Bar" />
    </StackPanel>
</Page>
...