0

私は3つのリストボックスを持っており、すべて同じタイプの2つの3つの別々の監視可能なコレクションにバインドされています。私のViewModelには、プロパティを介して公開された監視可能なコレクションがあります。これは一部のドラッグアンドドロップグループ化用です。ソースリストボックスでは、アイテムを2つの異なるリストにドラッグできます。しかし、私はユーザーがリストボックスアイテムを右クリックしてアイテムのプロパティを設定できるようにしたいのです。タイプ、名前など。3つのボックスすべての機能を同じにしたいので、でデータテンプレートを使用しています。これはうまく機能し、個々のアイテムをクリックするとコンテキストメニューがポップアップ表示されるので問題ありません。私の問題は、FieldTypeというプロパティが1つあることです。これは、4つの潜在的な値を持つ列挙型です。私の人生の間、MenuItemのIsCheckedプロパティをそのプロパティにバインドする方法を理解することはできません...とにかく機能的に。

<DataTemplate x:Key="SFTemplateWithContextMenu">
        <TextBlock Text="{Binding Path=FieldName}" ><!--Tag="{Binding DataContext, ElementName=Window}"-->
         <TextBlock.ContextMenu>
                <ContextMenu >
                    <ContextMenu.Resources>
                        <Configurator:EnumToBooleanConverter x:Key="EnumToBooleanConverterc" />
                    </ContextMenu.Resources>
                    <MenuItem  Header="Rename..." />
                    <MenuItem Header="Field Type">
                        <MenuItem.Resources>
                            <Configurator:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
                        </MenuItem.Resources>
                        <MenuItem  Header="String" IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=DataContext.FieldType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverterc}, ConverterParameter={x:Static Configurator:TypeDesc.String}, PresentationTraceSources.TraceLevel=High}"/>
                        <MenuItem  Header="Date" IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=DataContext.FieldType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static Configurator:TypeDesc.Date}}"/>
                        <MenuItem  Header="Barcode" IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=DataContext.FieldType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static Configurator:TypeDesc.BarCode}}" />
                    </MenuItem>
                </ContextMenu> 
            </TextBlock.ContextMenu>
        </TextBlock>
    </DataTemplate>

上記のコードでは、文字列、日付、およびバーコードMenuItemで、私がやろうとしていたことを確認できます(仕掛品であるコードが大好きです)。私の問題は、それが呼び出すべき公開されたプロパティです。ViewModelプロパティで、クリックされたアイテムに対応する監視可能なコレクション内のアイテムに到達する方法がわかりません。チェックされるかどうかを取得するためにバインディングに配置される値コンバーターEnumToBooleanがあります。問題は、監視可能なコレクション内の特定のアイテムを設定/取得しているプロパティです。

何かご意見は?さらにコードが必要ですか?何か明確にする必要がありますか?私はどれくらい近いですか?ちなみに、ViewModelコードはVB2010で書かれています。

ありがとうブライス

編集:私はエンジェルの提案を使用して次のことを試しました...

        <DataTemplate x:Key="SFTemplateWithContextMenu">
        <TextBlock x:Name="Field" Text="{Binding Path=FieldName}" >
         <TextBlock.ContextMenu PlacementTarget="{Binding ElementName=Field}">
                    <MenuItem  Header="Rename..." />
                    <MenuItem Header="Field Type">
                        <MenuItem.Resources>
                            <Configurator:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
                        </MenuItem.Resources>
                        <MenuItem  Header="Date" IsCheckable="True" IsChecked="{Binding PlacementTarget.DataContext.FieldType, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static Configurator:TypeDesc.String}, PresentationTraceSources.TraceLevel=High}"/>
                    </MenuItem>
            </TextBlock.ContextMenu>
        </TextBlock>
    </DataTemplate>

しかし、これは私に言うエラーを与えます...プロパティ要素にプロパティを設定できません。これがTextBloxとTextBoxの問題かどうかわかりませんか?あなたはあなたの例でTextBoxを使用しました...私の推測ではあなたのコードは同じことをするでしょう。それで私は次のことを試みました...

        <DataTemplate x:Key="SFTemplateWithContextMenu">
        <TextBlock x:Name="Field" Text="{Binding Path=FieldName}" ><!--Tag="{Binding DataContext, ElementName=Window}"-->
         <TextBlock.ContextMenu>
                <ContextMenu PlacementTarget="{Binding ElementName=Field}" >
                    <MenuItem  Header="Rename..." />
                    <MenuItem Header="Field Type">
                        <MenuItem.Resources>
                            <Configurator:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
                        </MenuItem.Resources>
                        <MenuItem  Header="Date" IsCheckable="True" IsChecked="{Binding PlacementTarget.DataContext.FieldType, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static Configurator:TypeDesc.String}, PresentationTraceSources.TraceLevel=High}"/>
                    </MenuItem>
                </ContextMenu>
            </TextBlock.ContextMenu>
        </TextBlock>
    </DataTemplate>

しかし、これによりバインディングエラーが発生します... System.Windows.Dataエラー:4:参照'ElementName=Field'でバインディングのソースが見つかりません。BindingExpression :(パスなし); DataItem = null; ターゲット要素は'ContextMenu'(Name =''); ターゲットプロパティは「PlacementTarget」(タイプ「UIElement」)です。

したがって、バインディングが機能していないようです。何かご意見は?

4

1 に答える 1

1

ContextMenuビジュアル ツリーの一部ではありません。したがって、デフォルトでは、適用される TextBlock の datacontext に \ bind を接続しません...

だからこれを行う2つの方法...

  1. それを個々の MenuItem の Binding に設定ContextMenu.PlacementTargetして参照します。Path

例えば

   <TextBox x:Name="MyTextBlock">
        <TextBox.ContextMenu PlacementTarget="{Binding ElementName=MyTextBlock}">
            <MenuItem 
                 Header="{Binding PlacementTarget.DataContext.MyHeader, 
                                  RelativeSource={RelativeSource
                                      AncestorType={x:Type ContextMenu}}}"
        </TextBox.ContextMenu>
  </TextBox>

上記の例では、メニュー項目をテキスト ボックスのデータ コンテキストに接続します。したがって、 で定義PlacementTargetしますContextMenu。この配置ターゲットは、2 種類のバインディングでのみ設定できます...ElementNameまたはStaticResource. そして、コンテキスト メニューが を介してビジュアル要素に接続されたら、meuitem のバインディングで をPlacementTarget使用して、データ コンテキスト プロパティを解決します。PathMyHeader

また

プロキシ要素アプローチを使用...

データグリッド列の可視性 MVVM をバインドする

于 2012-05-16T13:37:01.050 に答える