الطريقة الصحيحة للعثور على TabItem من القيادة ContextMenu

StackOverflow https://stackoverflow.com/questions/454962

  •  19-08-2019
  •  | 
  •  

سؤال

ولدي TabControl علبة الذي أنا وضع ContextMenu.

وجميع العناصر ContextMenu والأوامر الموضوعة.

<ContextMenu x:Key="tabMenu">
  <MenuItem Command="{x:Static tabs:TabCommands.Close}" />
  <MenuItem Command="{x:Static tabs:TabCommands.CloseAllButThis}" />
  <MenuItem Command="{x:Static tabs:TabCommands.CloseAll}" />
</ContextMenu>

ويتم توجيه جميع الأوامر، وحددت CommandBindings عدة مستويات فوق TabControl علبة.

ولذا فإن السؤال هو: في CommandBinding CanExecute / تنفيذ معالجات الأحداث، ما هي الطريقة الصحيحة لمعرفة الذي TabItem تم استدعاء القائمة؟ بواسطة صحيحة أعني تلك التي لن كسر إذا قمت بتغيير شيء من هذا القبيل القالب TabItem.

وأو قد يكون النهج كله خاطئ وأنا لا ينبغي استخدام الأوامر الموجهة لهذا؟ ولقد استخدمت في الأصل التوجيه لإضافة علامة تبويب جديدة القيادة التي تتطلب مفاتيح الاختصار.

وشكرا مقدما.

<القوي> UPDATE : ل

وحل إيغور هو أنظف من بوف المعماري (باستثناء أنني إزالة _ في ViewModel)، ولكن أريد أن يكون الأمر إغلاق قابلة لإعادة الاستخدام مستقلة عن ما لا بد TabControl علبة ل(منذ إغلاق / إغلاق جميع علامات التبويب الموجودة في كل أنواع التطبيقات ولا ترتبط لغويا إلى نموذج معين).

وبالإضافة إلى ذلك، لا يمكنني استخدام DataTemplate مخصص منذ لدي بالفعل قالب مخصص، وإن شاء subclasses ترث من شأنه أن يجعل حل قليلا overcomplicated.

هل كانت مفيدة؟

المحلول

ويبدو أنني وجدت الجواب نفسي، ومع ذلك فإنه unelegant للغاية:

<Style TargetType="MenuItem">
  <Setter Property="CommandTarget">
    <Setter.Value>
      <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}"
               Path="(ContextMenu.PlacementTarget)" />
    </Setter.Value>
  </Setter>
</Style>

<Style TargetType="TabItem">
  <Setter Property="ContextMenu" Value="{StaticResource tabMenu}" />
</Style>

وهكذا يمكنني إضافة ContextMenu إلى TabItem بدلا من TabControl علبة، وربط CommandTarget إلى TabItem.

ومن المثير للاهتمام ما إذا كان هناك إجابة أفضل.

نصائح أخرى

وبالتأكيد، هناك إجابة أفضل. كنت بحاجة إلى العمل مع الموديل / ViewModel، وليس عرضها. هنا حصول exmaple مبسط من قانون بلدي:

        <TabControl Margin="3" Grid.Column="1" Name="tbPages"
                    ItemsSource="{Binding DsmProject.Pages}" 
                    ItemTemplate="{DynamicResource TabItemTemplate}"
                    IsSynchronizedWithCurrentItem="True">
        </TabControl>
<DataTemplate x:Key="TabItemTemplate">
    <StackPanel Orientation="Horizontal" ContextMenu="{DynamicResource cmPages}">
        <ContentPresenter Content="{Binding Path=Name}"/>
    </StackPanel>
</DataTemplate>
<ContextMenu x:Key="cmPages">
    <MenuItem Header="Close" Command="cmd:DSM2100Commands.ClosePage" CommandParameter="{Binding}" />
</ContextMenu>

وهنا هو رمز، الذي يتعامل مع هذا الأمر.

تحليل منطقة "إغلاق صفحة"

    Private Sub ClosePageCmd(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
        ViewModel_.History.TakeCommmand(New cmdRemovePage(ViewModel_, e.Parameter))
    End Sub

    Private Sub CanClosePageCmd(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
        e.CanExecute = ViewModel_.DsmProject IsNot Nothing AndAlso ViewModel_.DsmProject.Pages.Count > 1
    End Sub

النهاية منطقة

وكما ترون، قانون بلدي ليس لديها الحاجة إلى معرفة التي تم النقر TabItem، تحتاج فقط إلى معرفة أي كائن البيانات كان لا بد لهذا TabItem. في أي حال، إذا كنت بحاجة إلى معرفة TabItem، الذي تم النقر يمكنك العثور عليها من قبل يحدها كائن البيانات إليها باستخدام الكائن ContainerGenerator وdatatemplate الخاص بك.

مع أطيب التمنيات من روسيا!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top