في WPF، كيف يمكنني تحديد عنصر TreeView ضمن مؤشراتي في النقر بزر الماوس الأيمن؟

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

  •  18-09-2019
  •  | 
  •  

سؤال

في WPF، عندما انقر بزر الماوس الأيمن فوق عنصر TreeView، أود اختيارها / تنشيطها قبل إظهار قائمة السياق.

هذا يبدو بسيطا جدا، لكن إدراج HierachicalDatatemplate يعقد الأشياء قليلا.

لدي TreeView التالية:

<TreeView 
            x:Name="trv"
            ContextMenu="{StaticResource contextMenu}"
            ItemTemplate="{StaticResource treeHierarchicalDataTemplate}"
            ItemsSource="{Binding Source={StaticResource meetingItems}}" >

            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <EventSetter Event="TreeViewItem.PreviewMouseRightButtonDown" Handler="trv_PreviewMouseRightButtonDown"/>
                    <Setter Property="IsExpanded" Value="True"></Setter>
                </Style>
            </TreeView.ItemContainerStyle>
        </TreeView>

وهنا هو معالج الحدث الخاص بي ...

private void trv_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    TreeViewItem item = sender as TreeViewItem;
    if (item != null)
    {
        item.Focus();
        e.Handled = true;
    }

}

لاحظ كيف أضيف رسالة Essiveet أعلاه. هذا يعمل تقريبا. ولكن لا يختار فقط عقدة TreeView مستوى الجذر (أي الوالد الجذر للعقدة التي انقر بزر الماوس الأيمن). قد يكون هذا بسبب قالب البيانات الهرمي؟ يمكن أن يحتوي هذا القالب على أطفال من نفس النوع.

هنا قالب البيانات الهرمية بلدي ...

<HierarchicalDataTemplate x:Key="treeHierarchicalDataTemplate" 
                          ItemsSource="{Binding Path=ChildMeetingItems}">
    <HierarchicalDataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=Red}" Value="True">
            <Setter TargetName="img" Property="Image.Source" Value="pack://siteoforigin:,,,/images/bookRed.png"></Setter>
        </DataTrigger>
    </HierarchicalDataTemplate.Triggers>
    <StackPanel 
        x:Name="treeViewItemPanel"
        Background="Transparent"
        Orientation="Horizontal">
        <Image Width="16" Height="16"  x:Name="img" Margin="0,0,4,0" Source="pack://siteoforigin:,,,/images/bookGreen.png"></Image>
        <TextBlock Foreground="DarkGray" Text="{Binding DisplayIndex}" Margin="0,0,5,0"></TextBlock>
        <TextBlock Text="{Binding Summary}"></TextBlock>
    </StackPanel>
</HierarchicalDataTemplate>

أي فكرة عن سبب تحديد عقدة الجذر فقط بدلا من العقد الطفل عند النقر بزر الماوس الأيمن؟

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

المحلول

ذلك لأن ItemContainerstyle لا تورثها العقد الفرعية. تحتاج إلى إضافة نفس EVESTESTER على Itemcontainerstyle o HierarchalDatemplate.

<HierarchicalDataTemplate x:Key="treeHierarchicalDataTemplate" 
                          ItemsSource="{Binding Path=ChildMeetingItems}">
    <HierarchicalDataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=Red}" Value="True">
            <Setter TargetName="img" Property="Image.Source" Value="pack://siteoforigin:,,,/images/bookRed.png"></Setter>
        </DataTrigger>
    </HierarchicalDataTemplate.Triggers>
    <StackPanel 
        x:Name="treeViewItemPanel"
        Background="Transparent"
        Orientation="Horizontal">
        <Image Width="16" Height="16"  x:Name="img" Margin="0,0,4,0" Source="pack://siteoforigin:,,,/images/bookGreen.png"></Image>
        <TextBlock Foreground="DarkGray" Text="{Binding DisplayIndex}" Margin="0,0,5,0"></TextBlock>
        <TextBlock Text="{Binding Summary}"></TextBlock>
    </StackPanel>

<HierarchicalDataTemplate.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <EventSetter Event="TreeViewItem.PreviewMouseRightButtonDown" Handler="trv_PreviewMouseRightButtonDown"/>                    
                </Style>
            </HierarchicalDataTemplate.ItemContainerStyle>
</HierarchicalDataTemplate>

نصائح أخرى

مجرد تعليق e.Handler=true من معالج الحدث الخاص بك.

مثله:

private void trv_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    TreeViewItem item = sender as TreeViewItem;
    if (item != null)
    {
        item.Focus();
       // e.Handled = true;
    }

}

كان لدي نفس المشكلة - لا يمكن الحصول على عنصر الشجرة المحدد المناسبة. وبدلا من استخدام PreviewMouseRightButtonDown حدث استخدمنا نفس الحدث ل StackPanel الذي يقوم أيضا بتخزين جميع البيانات اللازمة:

<StackPanel DataContext="{Binding}" MouseLeftButtonDown="StackPanel_MouseLeftButtonDown">
....
</StackPanel>

وكود معالج الأحداث وراء:

 private void StackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            StackPanel panel = sender as StackPanel;
            if(panel==null)return;
            MyTreeViewItem myClicked = panel.DataContext as MyTreeViewItem;
            if (myClicked == null) return;
...
}

MyTreeViewItem هو نوع مخصص لبيانات؛ myClicked الآن يخزن البيانات المرتبطة بند شجرة النقر. آمل أن يساعد شخص مثلي.

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