WPF MVVM Light数据绑定上下文菜单以列出视图项

时间:2014-07-22 03:49:30

标签: wpf listview mvvm contextmenu mvvm-light

我是WPF MVVM的新手,所以请耐心等待。我有一个ListView的用户列表,我想在这个ListView中添加一个ContextMenu。 ContextMenu应该能够编辑您在ListView中单击的任何用户。我将向您展示我目前拥有的代码,并勾画出来。我知道它目前无法正常工作,但基本思路是我需要ListView行中的UserID和ContextMenu中选择的信息。

<ListView ItemsSource="{Binding ListViewItems}" SelectionMode="Single">
        <ListView.ContextMenu DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
              <MenuItem Header="Test" Command="{Binding TestCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}" />
              <Separator></Separator>
              <MenuItem Header="Status" ItemsSource="{Binding DataContext.ObservableCollectionList}" DisplayMemberPath="Name">
                   <MenuItem.ItemContainerStyle>
                        <Style TargetType="MenuItem">
                            <Setter Property="Command" Value="{Binding DataContext.DataContext.UpdateCommand, RelativeSource={RelativeSource AncestorType=MenuItem}}"/>
                            <Setter Property="CommandParameter" Value="{Binding}"/>
                        </Style>
                   </MenuItem.ItemContainerStyle>
              </MenuItem>
        </ListView.ContextMenu>

        //users and stuff here

</ListView>

所以我的问题实际上是两个方面:

  1. 如何将ContextMenu附加到各个ListView项目。
  2. 如何将ListViewItem对象和ContextMenu选定对象传递给ViewModel RelayCommand?
  3. 或者,有更好的方法吗?

    更新后的代码:

    我已尝试过以下两条建议,但均无效。我将完全提供已经存在的其余代码。请记住,这是在标签之后。

     <ListView.ItemContainerStyle>
                    <Style TargetType="ListViewItem">
                        <Setter Property="Padding" Value="0"></Setter>
                        <Setter Property="Margin" Value="0"></Setter>
                        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                    </Style>
                </ListView.ItemContainerStyle>
                <ListView.ItemTemplate>
                    <ItemContainerTemplate>
                        <Border BorderThickness="0,0,0,2" BorderBrush="LightGray">
                        <Grid>
                            <Grid.Background>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0" Opacity="0.5">
                                    <GradientStop Color="White"/>
                                    <GradientStop Color="#FFDFE9F5" Offset="1"/>
                                </LinearGradientBrush>
                            </Grid.Background>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="25" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
    
    
                                <TextBlock  Grid.Column="1" Grid.Row="1" Text="{Binding Status}" FontStyle="Italic" Padding="0,0,0,3">
                                    <TextBlock.Style>
                                        <Style TargetType="TextBlock">
                                            <Style.Triggers>
                                                <DataTrigger Binding="{Binding IsOnDuty}" Value="False">
                                                    <Setter Property="Opacity" Value="0.3"  />
                                                </DataTrigger>
                                            </Style.Triggers>
                                        </Style>
                                    </TextBlock.Style>
                                </TextBlock>
                            </Grid>
                        </Border>
                    </ItemContainerTemplate>
                </ListView.ItemTemplate>
    

2 个答案:

答案 0 :(得分:2)

您可以利用Styles在个人ContextMenu上注入ListViewItems

这是你如何设置风格

<ListView ItemsSource="{Binding ListViewItems}"
          SelectionMode="Single">
    <ListView.Resources>
        <Style TargetType="ListViewItem">
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu DataContext="{Binding Path=PlacementTarget.ListView.DataContext, RelativeSource={RelativeSource Self}}">
                        <MenuItem Header="Test"
                                  Command="{Binding TestCommand}"
                                  CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext}" />
                        <Separator></Separator>
                        <MenuItem Header="Status"
                                  ItemsSource="{Binding ObservableCollectionList}"
                                  DisplayMemberPath="Name">
                            <MenuItem.ItemContainerStyle>
                                <Style TargetType="MenuItem">
                                    <Setter Property="Command"
                                            Value="{Binding DataContext.UpdateCommand, RelativeSource={RelativeSource AncestorType=MenuItem}}" />
                                    <Setter Property="CommandParameter"
                                            Value="{Binding}" />
                                </Style>
                            </MenuItem.ItemContainerStyle>
                        </MenuItem>
                    </ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>
    </ListView.Resources>
</ListView>

除非主ListView上需要上下文菜单,否则您可以删除ListView.ContextMenu

根据对视图模型的一些假设,您可能需要根据需要进行调整。

答案 1 :(得分:1)

这只是另一种做事方式 如果您不希望ContextMenu符合ListView定义,则可以使用此

<ContextMenu x:Key="ContextMenu" DataContext="{Binding Path=PlacementTarget.ListView.DataContext, RelativeSource={RelativeSource Self}}">
     <MenuItem Header="Test" Command="{Binding TestCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext}" />
     <Separator></Separator>
     <MenuItem Header="Status" ItemsSource="{Binding ObservableCollectionList}"
                              DisplayMemberPath="Name">
         <MenuItem.ItemContainerStyle>
              <Style TargetType="MenuItem">
                   <Setter Property="Command" Value="{Binding DataContext.UpdateCommand, RelativeSource={RelativeSource AncestorType=MenuItem}}" />
                   <Setter Property="CommandParameter" Value="{Binding}" />
              </Style>
        </MenuItem.ItemContainerStyle>
    </MenuItem>
</ContextMenu>
<ListView ItemsSource="{Binding ListViewItems}"
      SelectionMode="Single">
<ListView.Resources>
    <Style TargetType="ListViewItem">
        <Setter Property="ContextMenu" Value="{StaticResource ContextMenu}">
        </Setter>
    </Style>
</ListView.Resources>


虽然我个人更喜欢使用

<ListView.ItemContainerStyle>
     <Style TargetType="{x:Type ListViewItem}">

通过这种方式,您可以轻松地在不同的ContextMenus之间切换。