Получить имя TabItem в UserControl

У меня есть следующий код, который создает TabControl. Каждая вкладка содержит элемент управления UserControl (код приведен ниже), который отображает разные данные (одна показывает информацию о местном налоге, а другая показывает информацию о федеральном налоге или налоге штата).

Контроль вкладок

    <TabControl 
        Name="MappingTabs"
        Margin="6,7,7,8" Padding="6"
        Background="White" >
        <TabItem
            Name="LocalTaxTab"
            Padding="6,1"
            Header="Local">
            <AdornerDecorator>
                <DockPanel>
                    <Border Margin="7">
                        <GroupBox 
                            Name="LocalTaxesGroup">
                            <GroupBox.Header>
                                <TextBlock 
                                    FontWeight="Bold" 
                                    Text="Local Taxes">
                                </TextBlock>
                            </GroupBox.Header>
                            <StackPanel Margin="20,8,10,0"
                                        Orientation="Vertical">

                                <local:TaxCodeMappingHeader />

                                <!-- Note that a row is 25 high, -->
                                <ScrollViewer
                                        MaxHeight="250"
                                        >
                                    <ItemsControl  
                                            Name="LocalTaxCodeMappingControl"
                                            ItemTemplate="{StaticResource MappingRuleTemplate}" 
                                            BorderThickness="0" 
                                            AlternationCount="2" 
                                            IsTextSearchEnabled="False"
                                            HorizontalContentAlignment="Stretch"
                                            ItemsSource="{Binding TaxCodesCollection[0].CodeCollection, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}">
                                        <!--  ItemsSource="{Binding Source={StaticResource sortedCodeCollection}}">    -->
                                    </ItemsControl>
                                </ScrollViewer>

                                <local:TaxCodeMappingFooter DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"/>

                            </StackPanel>
                        </GroupBox>
                    </Border>
                </DockPanel>
            </AdornerDecorator>
        </TabItem>
        <TabItem
            Name="FedStateTaxesTab"
            Padding="6,1"
            Header="Federal\State">
            <AdornerDecorator>
                <DockPanel>
                    <Border Margin="7">
                        <GroupBox 
                            Name="FedStateTaxesGroup">
                            <GroupBox.Header>
                                <TextBlock 
                                    FontWeight="Bold" 
                                    Text="Federal \ State Taxes">
                                </TextBlock>
                            </GroupBox.Header>
                            <StackPanel Margin="20,8,10,0"
                                        Orientation="Vertical">

                                <local:TaxCodeMappingHeader />

                                <!-- Note that a row is 25 high, -->
                                <ScrollViewer
                                        MaxHeight="250"
                                        >
                                    <ItemsControl  
                                            Name="FedStateTaxCodeMappingControl"
                                            ItemTemplate="{StaticResource MappingRuleTemplate}" 
                                            BorderThickness="0" 
                                            AlternationCount="2" 
                                            IsTextSearchEnabled="False"
                                            HorizontalContentAlignment="Stretch"
                                            ItemsSource="{Binding TaxCodesCollection[1].CodeCollection, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}">
                                        <!--  ItemsSource="{Binding Source={StaticResource sortedCodeCollection}}">    -->
                                    </ItemsControl>
                                </ScrollViewer>

                                <local:TaxCodeMappingFooter DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"/>

                            </StackPanel>
                        </GroupBox>
                    </Border>
                </DockPanel>
            </AdornerDecorator>
        </TabItem>
    </TabControl>
</StackPanel>

UserControl (TaxCodeMappingFooter)

   <Button 
        Name="AddButton"
        Grid.Row="0"
        Grid.Column="0"
        Height="20" Width="20"
        Command="{Binding Path=DataContext.AddClickCommand}"
        CommandParameter="(want the tab name here)"
        Style="{StaticResource ImageButton}"
        ToolTip="Add a rule"
        local:AttachedImage.Image="{StaticResource AddImageSource}" />

UserControl (TaxCodeMappingFooter) содержит кнопку «Добавить», которую мне нужно подключить через RelayCommand к виртуальной машине. Мне нужно каким-то образом сообщить виртуальной машине, какая вкладка вызывает команду «Добавить», чтобы элемент можно было добавить в правильную коллекцию. Я подумал о том, чтобы отправить TabName, а затем отключить его, чтобы узнать, на какой вкладке находится пользователь.

Верна ли моя идея или это лучший способ сделать это, и если это правильно, как мне получить значение TabName, чтобы передать его обратно в качестве CommandParameter?


person BrianKE    schedule 18.11.2013    source источник
comment
Если вы используете MVVM, я бы сказал, что лучше всего каждая вкладка представляет собой View/ViewModel. Один пример здесь   -  person bland    schedule 18.11.2013
comment
Вы ошибаетесь. В случае MVVM вы должны использовать ViewModels для вкладок вместо жестко запрограммированных. В этом случае у вас будет доступ к текущему выбранному элементу.   -  person Andras Sebo    schedule 18.11.2013


Ответы (2)


Если вы собираетесь жестко кодировать свои элементы управления пользовательского интерфейса, как вы это сделали, то, возможно, ваш самый простой вариант — определить string DependencyProperty в вашем элементе управления TaxCodeMappingFooter:

public static readonly DependencyProperty TabNameProperty = DependencyProperty.
    Register("TabName", typeof(string), typeof(TaxCodeMappingFooter));

public string TabName
{
    get { return (string)GetTabName(TabNameProperty); }
    set { SetTabName(TabNameProperty, value); }
}

Затем вы можете установить его из своих TabItems:

<local:TaxCodeMappingFooter TabName="FedStateTaxesTab" DataContext="{Binding 
    RelativeSource={RelativeSource AncestorType=UserControl}}" />

И Bind к нему изнутри вашего контроля:

<Button Name="AddButton" Command="{Binding Path=DataContext.AddClickCommand}" 
    CommandParameter="{Binding TabName, RelativeSource={RelativeSource 
    AncestorType=TaxCodeMappingFooter}}" ... />
person Sheridan    schedule 18.11.2013

Как уже говорили другие, если вы правильно моделируете структуру модели представления, это не будет большой проблемой.

Если вы действительно хотите выполнить привязку к элементу-предку, вы можете использовать RelativeSource из FindAncestor, а затем указать AncestorType. Обратите внимание, что вам может понадобиться настроить AncestorLevel, если вы являетесь потомком более чем одного TabItem.

{Binding Path=Name
         RelativeSource={RelativeSource Mode=FindAncestor,
                                        AncestorType={x:Type TabItem}}}

(обтекание добавлено для ясности)

person Mike Strobel    schedule 18.11.2013