2016-03-24 13 views
2

を参照を送信:は、私はC#とWPFを使用していますが、私は以下を達成する方法が分からない、コンテキストメニューから親オブジェクトに

私はTreeViewItemsが含まれているツリービューを持っています。すべてのTreeViewItem.Headerには、アイコン、テキスト、およびContextMenuを含むスタックパネルがあります(コンテキストメニューはTreeView.Resourcesで定義されています。ユーザーがスタックパネルを右クリックするとコンテキストメニューが表示されます)。このMenuItemのClickイベントでは、カスタムダイアログが作成され、このダイアログには、そのコンテキストメニューを開いたTreeViewItemへの参照が必要です。

ここにはXAMLコードがあります。ツリービューが定義されている:

<TreeView Grid.Row="1" Margin="5, 3, 5, 3"> 
    <TreeView.Resources> 
     <ContextMenu x:Key="RoomsContextMenu"> 
      <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click"> 
       <MenuItem.Icon> 
        <Image Width="20" Height="20" Source="/GroupAddressCreatorWPF;component/Images/add.png" /> 
       </MenuItem.Icon> 
      </MenuItem> 
     </ContextMenu> 
    </TreeView.Resources> 

    <TreeViewItem> 
     <TreeViewItem.Header> 
      <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource RoomsContextMenu}"> 
       <Image Width="5" Height="5" Margin="3,0" 
         Source="/GroupAddressCreatorWPF;component/Images/red.png" /> 
       <TextBlock Text="Main area 1" /> 
      </StackPanel> 
     </TreeViewItem.Header> 
    </TreeViewItem> 
</TreeView> 

これは、カスタムダイアログを作成したメニュー項目からクリックイベントの実装である、と私はツリービューアイテムへのアクセスを必要とする場所:

private void addRom_Click(object sender, RoutedEventArgs e) 
{ 
    AddRoomsDialog roomsDialog = new AddRoomsDialog(???); 
    roomsDialog.Show(); 
} 
+0

addRom_Clickが呼び出されたときに、現在senderパラメータには何が含まれていますか? –

+0

Clickイベントを送信するオブジェクトへの参照を推測します(この場合はMenuItem – chincheta73

答えて

0

名前をツリービューに追加すると、インスタンスフィールドを介してアクセスできます。

<TreeView Margin="5, 3, 5, 3" x:Name="TreeView"> 

次に、あなたのコントロールまたはウィンドウのコンストラクタで、インスタンスフィールドのツリービューで現在アクティブなアイテムを格納するためのContextMenuOpeningとのContextMenuClosingイベントをリッスン。その場合は、クリックイベントハンドラでアクセスできます。

private TreeViewItem activeItem; 

public Window() 
{ 
    InitializeComponent(); 

    // sender is the TreeView itself. Just iterate through the items 
    // and retrieve the first one where IsMouseOver returns true. 
    TreeView.ContextMenuOpening += (sender, e) => 
    { 
     activeItem = ((TreeView) sender).Items.OfType<TreeViewItem>().FirstOrDefault(item => item.IsMouseOver); 
    }; 

    TreeView.ContextMenuClosing += (o, e) => 
    { 
     activeItem = null; 
    }; 
} 

private void addRom_Click(object sender, RoutedEventArgs e) 
{ 
    // Once we get here, activeItem will reference the TreeViewItem 
    // that was under the cursor when the context menu was opened. 
    AddRoomsDialog roomsDialog = new AddRoomsDialog(activeItem); 
    roomsDialog.Show(); 
} 

あるいは、のContextMenuOpeningイベントハンドラでRoutedEventArgs E変数がクリックされたアイテムへの参照を保持します。つまり、TextBlockまたはImageです。問題に該当する場合は、そのオブジェクトへの参照を格納することができます。

1

ありがとうlenkan。 XAMLファイルを変更して、ユーザーがツリービューで子を削除できるようにしなければなりませんでした。今私のXAMLファイルは次のようになります。

   <TreeView.Resources> 
        <ContextMenu x:Key="RoomsContextMenu"> 
         <MenuItem Header="Add Rooms" VerticalAlignment="Bottom" Click="addRom_Click"> 
          <MenuItem.Icon> 
           <Image Width="20" Height="20" Source="/GroupAddressCreatorWPF;component/Images/add.png" /> 
          </MenuItem.Icon> 
         </MenuItem> 
        </ContextMenu> 
        <HierarchicalDataTemplate DataType="{x:Type local:MainArea}" ItemsSource="{Binding Path=RoomCollection}"> 
         <Border Width="150" BorderBrush="RoyalBlue" BorderThickness="1" CornerRadius="2" Margin="2" Padding="2" > 
          <StackPanel Orientation="Horizontal" ContextMenu="{StaticResource RoomsContextMenu}"> 
           <Image Width="10" Height="10" Margin="3,0" 
            Source="/GroupAddressCreatorWPF;component/Images/blue.png" /> 
           <TextBlock Text="{Binding MainAreaName}" /> 
          </StackPanel> 
         </Border> 
        </HierarchicalDataTemplate> 

        <HierarchicalDataTemplate DataType="{x:Type local:Room}"> 
         <Border Width="132" BorderBrush="Green" BorderThickness="1" CornerRadius="2" Margin="1" > 
          <StackPanel Orientation="Horizontal"> 
           <Image Width="10" Height="10" Margin="3,0" 
            Source="/GroupAddressCreatorWPF;component/Images/green.png" /> 
           <TextBlock Text="{Binding RoomName}" /> 
          </StackPanel> 
         </Border> 
        </HierarchicalDataTemplate> 
       </TreeView.Resources> 
      </TreeView> 

問題は今のコードのこの部分に来る:

roomsTreeView.ContextMenuOpening += (senderContextMenu, eContextMenu) => 
{ 
    mMainAreaItem = ((TreeView)senderContextMenu).Items.OfType<TreeViewItem>().FirstOrDefault(item => item.IsMouseOver); 
}; 

ツリービュー内の項目は、ツリービューアイテム(彼らはMainAreaある)、mMainAreaItemではありませんので、上記のコードでは常に-1です。

roomsTreeView.ContextMenuOpening += (senderContextMenu, eContextMenu) => 
{ 
    mMainAreaItem = ((TreeView)senderContextMenu).Items.OfType<MainArea>().FirstOrDefault(item => item.IsMouseOver); 
}; 

しかしMainAreaがIsMouseOverプロパティが含まれていませんので、そのdoesn'tはコンパイル:私はまた、次の操作を実行しようとしています。これを簡単に修正する方法はありますか? (申し訳ありませんが、私はC#とWPFの新機能です)。

+0

)。実際のアイテムは何ですか?それはイメージかテキストですか? – lenkan

+0

MainAreaオブジェクトが必要なので、RoomCollectionにルームを追加できます。 – chincheta73

+0

これを達成する最も簡単な方法は、コンテキストメニューをBorder要素の中に置くことです。これにより、((FrameworkElement)sender).DataContextからmainareaにアクセスできます。 – lenkan

関連する問題