2012-03-07 18 views
0

ListView内には、GridViewがあり、ユーザーがListViewの「行」を右クリックしたときに元のデータオブジェクトにアクセスできるように設定しようとしています。 私はListViewのgridview部分がこれをもう少し難しくしていると思います。ListView/GridViewのContextMenu

どこに問題があるかを示すサンプルを作成しました。ユーザーが行Person1を右クリックすると、MenuItem_ClickハンドラのPersonClassデータオブジェクトにアクセスできます。私はPlacementTargetで試してみましたが、取得するのはnullオブジェクトまたはMenuItem型のオブジェクトだけです。

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 

    <Window.Resources>   
     <ContextMenu Name="cm" x:Key="TestContextMenu"> 
      <MenuItem Header="Context1" Click="MenuItem_Click"/> 
      <MenuItem Header="Context2"/> 
      <MenuItem Header="Context3"/> 
     </ContextMenu> 
    </Window.Resources> 

    <Grid> 
     <ListView Margin="20" Name="TestListView" SelectionMode="Multiple"> 

      <ListView.ItemContainerStyle> 
       <Style TargetType="ListViewItem"> 
        <Setter Property="ContextMenu" Value="{StaticResource TestContextMenu}" /> 
       </Style> 
      </ListView.ItemContainerStyle> 

      <ListView.View> 
       <GridView> 
        <GridViewColumn Header="FirstName" Width="200" DisplayMemberBinding="{Binding Path=FirstName}"/> 
        <GridViewColumn Header="Surname" Width="200" DisplayMemberBinding="{Binding Path=Surname}"/> 
       </GridView> 
      </ListView.View> 

     </ListView> 
    </Grid> 

</Window> 

コード:

Class MainWindow 

    Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded 

     Dim Person1 As New PersonClass("John", "Fletcher") 
     Dim Person2 As New PersonClass("Bob", "Smith") 

     Dim ListOfPersons As New List(Of PersonClass) 
     ListOfPersons.Add(Person1) 
     ListOfPersons.Add(Person2) 

     TestListView.ItemsSource = ListOfPersons 

    End Sub 

    Private Sub MenuItem_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) 

     MsgBox(e.OriginalSource.ToString) 
     MsgBox(sender.ToString) 
     MsgBox(e.Source.ToString) 


    End Sub 

End Class 


Public Class PersonClass 

    Private _firstName As String 
    Private _surname As String 

    Public Property FirstName() As String 
     Get 
      Return _firstName 
     End Get 
     Set(ByVal Value As String) 
      _firstName = Value 
     End Set 
    End Property 

    Public Property Surname() As String 
     Get 
      Return _surname 
     End Get 
     Set(ByVal Value As String) 
      _surname = Value 
     End Set 
    End Property 

    Public Sub New() 
    End Sub 

    Public Sub New(FirstName As String, Surname As String) 
     Me.FirstName = FirstName 
     Me.Surname = Surname 
    End Sub 

End Class 

答えて

0

最終的にPlacementTargetが機能するようになりました。以下のコードがあります。その理由は、選択された項目がうまくいかなかったからです。項目がすでに選択されていて右クリックしている場合は、行は選択解除されています。

変更initalポストからWindow.Resourcesへ:

<Window.Resources> 
    <ContextMenu Name="cm" x:Key="TestContextMenu" > 
     <MenuItem Header="Context1" Click="MenuItem_Click" > 
      <MenuItem.DataContext> 
       <Binding RelativeSource="{RelativeSource AncestorType={x:Type ContextMenu}}" Path="PlacementTarget.DataContext"/> 
      </MenuItem.DataContext> 
     </MenuItem> 
     <MenuItem Header="Context2"/> 
     <MenuItem Header="Context3"/> 
    </ContextMenu> 
</Window.Resources> 

Private Sub MenuItem_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) 

    Dim MenuI As New MenuItem 
    MenuI = TryCast(sender, MenuItem) 

    Dim APerson As New PersonClass 
    APerson = MenuI.DataContext 

    MsgBox(APerson.FirstName) 

End Sub 
0

私はあなたが修正理解していれば、この単純なコードは(イベントMenuItem_Clickで)トリックを行う必要があります。あなたが唯一の最初の項目は、コードで使用されます。このコードで、複数の選択モードを設定している

If TestListView.SelectedItem IsNot Nothing Then 
    Dim person As PersonClass = TestListView.SelectedItem 
    //Do something with "person" 
Else 
    MsgBox("No item selected!") 
End If 

注:また、各項目はすでにPersonClassインスタンスを表して明示的なキャストが必要とされていないことに注意してください。複数の商品の場合は、次のコードを使用してください:

If TestListView.SelectedItems.Count > 0 Then 
    For Each person As PersonClass In TestListView.SelectedItems 
     //Do something with "person" 
    Next 
End If 

+0

ご提案いただきありがとうございます。 – SpeedBird527