1

私はこのトピックに関する答えがほとんどないことを知っています。しかし、私の場合、それらのどれも機能していませんでした。

私はListViewスタイルとを持っていItemContainerStyleます。では、リスト内のアイテムが選択されているかどうかに応じItemContainer Styleて異なるトリガーを使用するために、いくつかのトリガーを定義します。DataTemplate次に、最後にDatatemplate、コマンドを含むコンテキストメニューがあります。問題は、コマンドをビューモデルにバインドする方法です。

これはListViewです:

    <ListView
        x:Name="lstPersons"
        Grid.Row="1"
        Style="{StaticResource ListViewStyle}"
        ItemContainerStyle="{StaticResource ItemContainerStyle}"
        DataContext="{Binding}"
        ItemsSource="{Binding Path=Persons}"
        Tag="{Binding}"
        SelectedItem="{Binding Path=SelectedPerson, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    </ListView>

これらは、スタイル、データテンプレート、およびコンテキストメニュー(リソースディクショナリで定義)です。コンテキストメニューのコマンドが機能しません....:

    <ContextMenu x:Key="SelectedItemContextMenu">
        <MenuItem
            Header="Do Something"
            Command="{Binding Path=DataContext.DoSomethingCmd, ElementName=LayoutRoot}">
        </MenuItem>
        <MenuItem
            Header="Do Something"
            Command="{Binding PlacementTarget.Tag.DoSomethingCmd, RelativeSource={RelativeSource AncestorType=ContextMenu}}">
        </MenuItem>
    </ContextMenu>

<DataTemplate
    x:Key="ItemTemplate">
    <Canvas
        Margin="4"
        Width="60"
        Height="60"
        Background="LightGray">
        <TextBlock
            Foreground="Black"
            Margin="2 0 0 0"
            Opacity="0.5"
            FontFamily="Segoe UI"
            Text="{Binding Path=FirstName}" />
    </Canvas>
</DataTemplate>

<DataTemplate
    x:Key="ItemSelectedTemplate">
    <Grid>
        <Border
            BorderBrush="Black"
            BorderThickness="1"
            Margin="3"
            ContextMenu="{DynamicResource SelectedItemContextMenu}">
            <Canvas
                Width="60"
                Height="60"
                Background="LightBlue">
                <TextBlock
                    Foreground="Black"
                    Margin="2 0 0 0"
                    Opacity="0.5"
                    FontFamily="Segoe UI"
                    Text="{Binding Path=FirstName}" />
            </Canvas>
        </Border>
    </Grid>
</DataTemplate>


<!--style of the listviewitem-->
<Style
    TargetType="{x:Type ListViewItem}"
    x:Key="ItemContainerStyle">
    <Setter
        Property="ContentTemplate"
        Value="{StaticResource ItemTemplate}" />
    <Style.Triggers>
        <Trigger
            Property="IsSelected"
            Value="True">
            <Setter
                Property="ContentTemplate"
                Value="{StaticResource ItemSelectedTemplate}" />
        </Trigger>
    </Style.Triggers>
</Style>


<!--style of the listview-->
<Style
    TargetType="{x:Type ListBox}"
    x:Key="ListViewStyle">
    <Setter
        Property="Template">
        <Setter.Value>
            <ControlTemplate
                TargetType="{x:Type ListBox}">
                <Grid>
                    <Border>
                        <ScrollViewer
                            Focusable="false">
                            <WrapPanel
                                IsItemsHost="True"
                                Orientation="Horizontal"
                                Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"/>
                        </ScrollViewer>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
4

3 に答える 3

0

この場合、VMコマンドの代わりにRoutedCommandsを使用する必要があります。RoutedCommandをContextMenuにバインドします。そのために必要なのは静的オブジェクト参照だけなので、それらを見つけることは問題にはなりません。次に、コマンドを処理する必要があるコントロールに適切なCommandBindingを設定します(List-ViewModelまたはItem-ViewModelのどちらでコマンドを処理するかに応じて、ListViewまたはListViewItemのいずれか)。これらのコントロールはViewModelを認識しているため、それらへのバインドは問題になりません。WPFに組み込まれているコマンドルーティングのプロセスを通じて、コンテキストメニューはそのコマンドの適切なターゲットを自動的に見つけます。

MVVMに適した方法でCommandBindingを設定する方法のガイダンスについては、http://wpfglue.wordpress.com/2012/05/07/commanding-binding-controls-to-methods/を参照することをお勧めします。

于 2012-07-28T08:09:12.337 に答える
0

あなたはRelativeSourceを使うことができます:

  <ContextMenu x:Key="SelectedItemContextMenu">
            <MenuItem
            Header="Do Something"
            Command="{Binding Path=DataContext.DoSomethingCmd, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">
            </MenuItem>           
        </ContextMenu>
于 2012-07-27T21:34:05.897 に答える
0

ContextMenu はデータ テンプレート内で使用されます。「LayoutRoot」の別の名前スコープに配置され、ElementName バインディングが機能しません。また、コンテキスト メニューの PlacementTarget は Border であり、タグを設定していません。したがって、2 番目のコマンドも機能しません。

ListBox レベル (または LayoutRoot?) でコマンドを実装しているようです。コンテキスト メニューを ListBox に配置し、ListBox.SelectedItem を使用して現在の選択を見つけてロジックを適用する方が簡単な場合があります。

于 2012-07-27T21:24:52.443 に答える